gwcoffey
gwcoffey

Reputation: 5921

Convert object property to array with one element per key

I am trying to use Jolt to transform an object into an array with one array element per key in the original object. I'd like the output objects to include the original key as a property, and preserve any properties from the source value. And I need to handle three scenarios for the input properties:

Here's an example:

{
  "operations": {
    "foo": null,
    "bar": {},
    "baz": {
      "arbitrary": 1
    }
  }
}

And the desired output"

{
  "operations": [
    {
      "operation": "foo"
    },
    {
      "operation": "bar"
    },
    {
      "operation": "baz",
      "arbitrary": 1
    }
  ]
}

Note: foo, bar and baz are arbitrary here. It needs to handle any property names inside the operations object.

This is really close to what I want:

[
  {
    "operation": "default",
    "spec": {
      "operations": {
        "*": {}
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "operations": {
        "*": {
          "$": "operations[].operation"
        }
      }
    }
  }
]

But it drops "arbitrary": 1 from the baz operation.

Alternately this keeps the properties in the operations, but doesn't add a key for the operation name:

[
  {
    "operation": "default",
    "spec": {
      "operations": {
        "*": {}
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "operations": {
        "*": {
          "@": "operations[]"
        }
      }
    }
  }
]

Any help getting both behaviors would be appreciated.

Upvotes: 1

Views: 82

Answers (1)

Barbaros Özhan
Barbaros Özhan

Reputation: 65228

You can use one level of shift transformation spec along with symbolical usage(wildcards) rather than repeated literals such as

[
  {
    "operation": "shift",
    "spec": {
      "*s": {
        "*": {
          "$": "&2[#2].&(2,1)",
          "*": "&2[#2].&"
        }
      }
    }
  }
]

where

  • &2 represents going 2 levels up the tree by traversing { signs twice in order to pick the key name operations (if it were only &->eg.identicals &(0) or &(0,0), then it would traverse only the colon and reach $ to grab its value)

  • [#2] also represents going 2 levels of traversing { signs and : sign, as it's already located on the Right Hand Side of the spec, in order to ask that reached node how many matches it has had

  • &(2,1) subkey lookup represents going 2 levels up the tree and grab the reached key name of the object by the first argument, and which part of the key, which's partitioned by * wildcard, to use by the second argument. (in this case we produce the literal operation without plural suffix)

  • * wildcard, which's always on the Left Hand Side, represents the rest of the attributes(else case).

the demo on the site http://jolt-demo.appspot.com is

enter image description here

Upvotes: 1

Related Questions