jsonjqcartesian-product

How to make a certain double cartesian product with jq?


Suppose I have this dataset:

{"id": 99, "labeled_values": [["one", "green"], ["two", "red"], ["three", "blue"]], "flavors": ["hot", "cold"]}
{"id": 100, "labeled_values": [["four", "green"], ["five", "red"]], "flavors": ["hot"]}

and I would like this output (tab-separated):

99 one green hot
99 two red hot
99 one green cold
99 two red cold
100 four green hot
100 five red hot

This code (from here) works without the flavors:

$ cat tmp/foo.ndjson | jq -r '[.id] + .labeled_values[] | @tsv'
99  one green
99  two red
99  three   blue
100 four    green
100 five    red

Here is a failed attempt to add the flavor. It concatenates all the flavors, not one at a time.

$ cat tmp/foo.ndjson | jq -r '[.id] + .labeled_values[] + .flavors | @tsv'
99  one green   hot cold
99  two red hot cold
99  three   blue    hot cold
100 four    green   hot
100 five    red hot

Solution

  • You can use the combinations filter:

    jq -r '[[.id],.labeled_values,.flavors] | combinations | flatten | @tsv' file.json
    
    99  one green   hot
    99  one green   cold
    99  two red hot
    99  two red cold
    99  three   blue    hot
    99  three   blue    cold
    100 four    green   hot
    100 five    red hot