jqlang / jq

Command-line JSON processor
https://jqlang.github.io/jq/
Other
30.48k stars 1.58k forks source link

Unwind document based on array #1104

Open McStork opened 8 years ago

McStork commented 8 years ago

Hello, I have been looking for a feature that allows to split a document into multiple ones, based on its array. After some search I haven't found anything but an operation in MongoDB.

The feature is explained on this MongoDB page.

It would be really great if jq could support this. :)

McStork commented 8 years ago

https://stedolan.github.io/jq/manual/#Objects-{} is the answer

pkoppstein commented 8 years ago

The following filter, unwind/1, would I believe be worth considering as a standard jq builtin. It is a close relative of .[] and although it is easy enough to implement in jq, it would be nice to have at-hand:

# Given an object with an arrayed-value key, say .k, , unwind(.k) produces
# a stream of objects identical to the original object except
# that at the key, the value is taken sequentially from the array.
# Note that unwind/1 can be applied in a pipeline to unwind different keys,
# e.g. {"x":[1,2], "y":[3,4]} | unwind(.x) | unwind(.y)
# produces the stream of four objects beginning with {"x":1, "y":3}

def unwind(key): (key | .[]) as $value | . + ({} | (key = $value));

Example:

    {"x":[1,2], "y":[3,4]} | unwind(.x) | unwind(.y)

produces:

{"x":1,"y":3}
{"x":1,"y":4}
{"x":2,"y":3}
{"x":2,"y":4}

[@slapresta - If you get around to adding filter/1 in a PR, please feel free to include the above as well if you think it is worthwhile.]

dpnishant commented 2 years ago

Not sure if this is still relevant after 6+ years, but here is what I did to get an $unwind like output. Input: { "x" : [ 1, 2 ], "y" : [ 3, 4 ] } jq Filter: [.] | map(. + { x: .x[], y: .y[] }) | .[] Output:

{
  "x": 1,
  "y": 3
}
{
  "x": 1,
  "y": 4
}
{
  "x": 2,
  "y": 3
}
{
  "x": 2,
  "y": 4
}

jqPlay Snippet: https://jqplay.org/s/Fd5YqQjyJzU