I’m trying to combine two arrays with nested components into a new array. Best explained with example:
InputValues1 = [
{
"Values": [
{"Input1": 1, "Input2": -1},
{"Input1": 1, "Input2": -2},
{"Input1": 2, "Input2": -2},
{"Input1": 4, "Input2": -4}
],
"Name": "AA",
"key": 1
},
{
"Values": [
{"Input1": 1, "Input2": -2},
{"Input1": 3, "Input2": 5},
{"Input1": 3, "Input2": 2},
{"Input1": 1, "Input2": -2}
],
"Name": "AB",
"key": 2
}
]
InputValues2 = [
{
"Values": [
{"Input1": 3, "Input2": 2},
{"Input1": 2, "Input2": 1},
{"Input1": 1, "Input2": 1},
{"Input1": 1, "Input2": 6}
],
"Name": "BA",
"key": 1
},
{
"Values": [
{"Input1": 30, "Input2": 1},
{"Input1": 6, "Input2": 2},
{"Input1": 1, "Input2": 2},
{"Input1": 1, "Input2": 8}
],
"Name": "BB",
"key": 2
}
]
The new combined output needs to be:
CombinedOutput = [
{
"Values": [
{"Input1": 4, "Input2": 1},
{"Input1": 3, "Input2": -1},
{"Input1": 3, "Input2": -1},
{"Input1": 5, "Input2": 2}
],
"Name": "AABA",
"key": 11
},
{
"Values": [
{"Input1": 31, "Input2": -1},
{"Input1": 9, "Input2": 7},
{"Input1": 4, "Input2": 4},
{"Input1": 2, "Input2": 6}
],
"Name": "ABBB",
"key": 22
}
]
So I’m looking to sum the nested Values arrays together, and concatenate the Name and key values.
I’m thinking the map function might be useful here, but I’m a little lost as to how to deal with the nested aspect as well as not create a mess with for loops.
I’ve shown the InputValues as having 2 entries each, but this could be larger, so I’m worried about my crude thinking of for loops.
6
Answers
As you mentioned, you can use
.map()
. Below, I’m using.map()
in a function I’ve created calledmerge
to map each object to a transformed object. Each transformed object is built by usingObjeect.fromEntries()
andObject.entries()
to iterate and access the current object’s keys/values. The transformed object has the same keys from the current object, but the values are transformed. If the current value is an array, I recursively callmerge()
to perform the same logic on the nested arrays and transform the inner objects. If it’s not an array, then we merge the values together based on your rules – If the key is eitherName
orkey
, you concatenate, otherwise we add. I’ve defined these rules in an object, that’s used by a callback function you can pass tomerge
and then called with the two values we’re trying to combine together:I suggest keeping your head and breaking the problem down into small manageable chunks. Don’t be afraid to use lots of functions.
You can use the
map
function to iterate over the arrays and combine them.Using a
Map
to iterate over two input arrays in parallel. For each pair of elements, a newobject
is created with the concatenated value, name, and key. Values are combined by iterating through the "values" array in parallel and creating a new object for each pair of values.The Map function is used to iterate over the "Values" array in parallel, and the "+" operator adds values. The
parseInt
function is used to convert concatenated keys to integers. I assume that the two input arrays are the same length and that each object’s "value" array is the same length. If not, you may need to add an error-checking code.You could separate the functions for merging.
It looks like you can solve that with this small generic function
It accepts two arrays or objects and creates a new array/object by applying a callback function to the "left" and "right" values.
The callback in your case would be a function that either adds arguments if they are scalars or recursively zips them otherwise:
Putting it all together:
It’s not clear from your post what you’re doing with the
key
key, so this is left as an exercise (hint: in theadder
add a branchif (key === 'key') { ... }
).Just iterate items in the second array, find corresponding items from the first one (create a copy of it) and add values.
The trick here that the key should be combined too, but we need to find the items from the first array, so combine keys under
_key
property and then replace it tokey
in the end.As you see this make the code very fast more than 15x faster than the other solutions.