Reputation: 293
Is there any recommended approach or function to combine the fn functionality of R.mergeWith with n list items, like R.mergeAll?
I have
const data = [
{ a: 1, b: 2, c: 0, d: { e: 3 }},
{ a: 1, c: -1 },
{ a: 1, b: 4, c: 0, d: { e: 2 }}
]
and want to sum all values by key, to return
{ a: 3, b: 6, c: -1, d: { e: 5 }}
I've tried something like
R.mapAccum((a, b) => R.mergeWith(R.sum, a, b), {}, data)
(in REPL) guessing what I'm after is a way to mergeWith the previous and current object, through some fn.
Any ideas how I could do that in a terse, pure way with a functional library? I prefer Ramda, but anything would be great.
Upvotes: 0
Views: 365
Reputation: 50807
Ramda does not currently have a mergeDeep
or mergeDeepWith
function. But it's likely to be added soon. See PR 1867.
With that in place, you could simply do
R.reduce(R.mergeDeepWith(R.add), {}, data)
You can see a simulation of what this would be like in the REPL.
(You need to use add
rather than sum
because reduce
means working with one pair of objects at a time. add
is for two numbers, sum
is for a list of them.)
Upvotes: 1
Reputation:
Assuming that you have no cyclic structures in your object, this will solve your problem.
function merge(array){
// Returns merged array
return mergeSubArray(array);
// This function recursively process all sub-arrays
function mergeSubArray(subArray){
// Sum all properties of all objects in the array
return subArray.reduce(function(previousObject, currentObject){
// Get all properties of an object
Object.keys(currentObject).forEach(function(keyOfCurrentObject){
/*
For all properties we need to check whether this type if number or object.
If we encountered a number, we simply add it to previous sum.
Otherwise, if it is an object, call this function to it.
*/
if(typeof previousObject[keyOfCurrentObject] == 'number'){
previousObject[keyOfCurrentObject] += currentObject[keyOfCurrentObject];
}else{
previousObject[keyOfCurrentObject] = mergeSubArray([previousObject[keyOfCurrentObject], currentObject[keyOfCurrentObject]]);
}
});
// Returns merged objects
return previousObject;
});
}
}
Upvotes: 2