Quantcast
Channel: Active questions tagged jq - Stack Overflow
Viewing all articles
Browse latest Browse all 657

JQ will not deep copy arrays with recursive algorithm

$
0
0

When using this algorithm:

jq -s 'def deepmerge(a;b):             reduce b[] as $item (a;               reduce ($item | keys_unsorted[]) as $key (.;                 $item[$key] as $val | ($val | type) as $type | .[$key] =                 if ($type == "object") then                   deepmerge({}; [if .[$key] == null then {} else .[$key] end, $val])                 elif ($type == "array") then                   (.[$key] + $val | unique)                 else                   $val                 end)               );             deepmerge({}; .)' test1.json test2.json > merged-1.json

nested arrays are not concatenated/merged, but copied sequentially. I assume this is because when the method stack created by the recursive algorithm unwinds, values are written in the order node >> root, and deeper nested child values are thus always overwritten by their higher parents.

Input files:

test1.json

{"item1" : "test1","item2" : "test2","nestedItemsArray1" : [{"nestedItem1Item1" : "nestItem1Item1","nestedItem1Array1" : ["nestedItem1Array1Item1", "nestedItem1Array1Item2"]   },  {"nestedItem1Item1" : "nestItem1Item2","nestedItem1Array1" : ["nestedItem1Array1Item3", "nestedItem1Array1Item4"]  }]}

test2.json

{"item1" : "test3","item2" : "test4","array1" : [ "array1item3", "array1item4" ],"nestedItemsArray1" : [{"nestedItem1Item1" : "nestItem1Item1","nestedItem1Array1" : ["nestedItem1Array1Item5", "nestedItem1Array1Item6"]  },  {"nestedItem1Item1" : "nestItem1Item2","nestedItem1Array1" : ["nestedItem1Array1Item7", "nestedItem1Array1Item8"]  }]}

Actual result:

{"item1": "test3","item2": "test4","nestedItemsArray1": [    {"nestedItem1Item1": "nestItem1Item1","nestedItem1Array1": ["nestedItem1Array1Item1","nestedItem1Array1Item2"      ]    },    {"nestedItem1Item1": "nestItem1Item2","nestedItem1Array1": ["nestedItem1Array1Item3","nestedItem1Array1Item4"      ]    },    {"nestedItem1Item1": "nestItem1Item1","nestedItem1Array1": ["nestedItem1Array1Item5","nestedItem1Array1Item6"      ]    },    {"nestedItem1Item1": "nestItem1Item2","nestedItem1Array1": ["nestedItem1Array1Item7","nestedItem1Array1Item8"      ]    }  ],"array1": ["array1item3","array1item4"  ]}

Expected result:

{"item1": "test3","item2": "test4","nestedItemsArray1": [    {"nestedItem1Item1": "nestItem1Item1","nestedItem1Array1": ["nestedItem1Array1Item1","nestedItem1Array1Item2","nestedItem1Array1Item5","nestedItem1Array1Item6"      ]    },    {"nestedItem1Item1": "nestItem1Item2","nestedItem1Array1": ["nestedItem1Array1Item3","nestedItem1Array1Item4","nestedItem1Array1Item7","nestedItem1Array1Item8"      ]    }  ],"array1": ["array1item3","array1item4"  ]}

Of course this is just one array deep, but I would like this to work on any number of nested levels, regardless of values being nested inside arrays or objects.


Viewing all articles
Browse latest Browse all 657

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>