Search code examples
jsonata

jsonata capitalize recursive object keys


i need to capitalize recursively the object keys

[
  {
    "alpha": {
      "type": "triangle"
    },
    "beta": {
      "type": "cube",
      "nestedArr":[1,2,3]
    }
  },
  {"aaa":1},
  "goodbye",
  ["hello","world"]
]

expected result the same but with capitalized keys in all objects:

[
  {
    "Alpha": {
      "Type": "triangle"
    },
    "Beta": {
      "Type": "cube",
      "NestedArr":[1,2,3]
    }
  },
  {"Aaa":1},
  "goodbye",
  ["hello","world"]
]

so far i have following jsonata transformation:

(
    $norm := function($o) {(
        $t := $type($o);
        $t = "object" ? $merge($each($o, function($v,$k) {
            { $uppercase($substring($k,0,1)) & $substring($k,1) : $norm($v) }
        }))
        :
        $t = "array" ? $o.($norm($))
        :
        $o
    )};
    $norm($)
)

result is close to what i need but something wrong with last array:

[
  {
    "Alpha": {
      "Type": "triangle"
    },
    "Beta": {
      "Type": "cube",
      "NextedArr": [ 1, 2, 3 ]
    }
  },
  {
    "Aaa": 1
  },
  "goodbye",
  "hello",
  "world"
]

appreciate any help to achieve the goal

https://try.jsonata.org/H0plepi5G


Solution

  • Due to how JSONata handles sequences, there are certain expressions when an array of arrays would be flattened by default.

    In your case, it's the $o.($norm($)) expression.

    There are probably other ways to solve it, but I've noticed myself that if I use the $map function instead of the map operator, the flattening does not happen:

    $map($o, function($i) {$norm($i)}) or just $map($o, $norm)

    Here's the full expression:

    (
        $norm := function($o) {(
            $t := $type($o);
            $t = "object" ? $merge($each($o, function($v,$k) {
                { $uppercase($substring($k,0,1)) & $substring($k,1) : $norm($v) }
            }))
            :
            $t = "array" ? $map($o, $norm})
            :
            $o
        )};
        $norm($)
    )
    

    Check it out on the Stedi playground: https://stedi.link/9R5rKgs