Reputation: 73
I have an array of objects like this:
arr = [
{ a: "dog", b: 8, c: "male", d: "big", e: 100 },
{ a: "dog1", b: 5, c: "female", d: "big", e: 200},
{ a: "dog2", b: 18, c: "female", d: "big", e: 350},
{ a: "dog2", b: 18, c: "female", d: "big", e: 350},
{ a: "dog", b: 3, c: "male", d: "big", e: 100 },
{ a: "dog", b: 8, c: "male", d: "big", e: 100 },
];
I want to create a new array containing only the property a
and the sum of e
of those objects that have the same values for b
, c
and d
, so that I'll have and array like this:
arr2 = [
{ a: "dog", e: 300 },
{ a: "dog2", e: 700},
];
I've already tried to use a map
function inside a map
function looking for the elements that have the same properties b
, c
and d
, then pushing the result in the arr2
, but it pushes every time all the objects of my initial arr
.
Upvotes: 1
Views: 1950
Reputation: 15530
If you're looking for vanilla JS solution (no lodash), you may come up with something, adjustable to arbitrary group key property and property to summarize with Array.prototype.reduce()
:
Map
, having desired property as a key;Map
items, based on the matching keyMap.prototype.values()
of that Map
into arrayconst src = [
{ a: "dog", b: 8, c: "male", d: "big", e: 100 },
{ a: "dog1", b: 5, c: "female", d: "big", e: 200},
{ a: "dog2", b: 18, c: "female", d: "big", e: 350},
{ a: "dog2", b: 18, c: "female", d: "big", e: 350},
{ a: "dog", b: 3, c: "male", d: "big", e: 100 },
{ a: "dog", b: 8, c: "male", d: "big", e: 100 },
]
const summarizeValueByKey = (arr, key, val) =>
[...arr
.reduce((acc,{[key]: keyProp, [val]: valProp}) => {
const group = acc.get(keyProp)
group
? group[val] += valProp
: acc.set(keyProp, {[key]: keyProp, [val]: valProp})
return acc
}, new Map)
.values()]
console.log(summarizeValueByKey(src, 'a', 'e'))
Upvotes: 1
Reputation: 30675
You could use Array.reduce
to create a map of the array elements, using b,c and d combined as the key.
Once we have this map, we can use Object.values()
to get an array as the desired result.
arr = [
{ a: 'dog', b: 8, c: 'male', d: 'big', e: 100 },
{ a: 'dog1', b: 5, c: 'female', d: 'big', e: 200},
{ a: 'dog2', b: 18, c: 'female', d: 'big', e: 350},
{ a: 'dog2', b: 18, c: 'female', d: 'big', e: 350},
{ a: 'dog', b: 3, c: 'male', d: 'big', e: 100 },
{ a: 'dog', b: 8, c: 'male', d: 'big', e: 100 },
];
const result = Object.values(arr.reduce((acc, cur) => {
// Create a key from b,c,d..
const key = cur.b + cur.c + cur.d
acc[key] = acc[key] || { a: cur.a, e: 0 };
acc[key].e += cur.e;
return acc;
}, {}))
console.log('Result:', result);
Upvotes: 3