I have this simple array, which I want to merge key b value if key a in the whole array matches.
const array = [
{a: 1, b: ['Foo']},
{a: 1, b: ['Bar']},
{a: 1, b: ['Baz']},
{a: 2, b: ['Foo']},
{a: 3, b: ['Foo']},
]
into
const array = [
{a: 1, b: ['Foo','Bar','Baz']},
{a: 2, b: ['Foo']},
{a: 3, b: ['Foo']},
]
is there a way to do it? Any help would be appreciated!
EDIT 1 : What I am lacking here is the logic to grab all similar key a
Use reduce to iterate over the array of objects to create an object where the keys match the object's a value, adding the various b values to their arrays. Then use Object.values to create a new array.
const arr = [
{a: 1, b: ['Foo']},
{a: 1, b: ['Bar']},
{a: 1, b: ['Baz']},
{a: 2, b: ['Foo']},
{a: 3, b: ['Foo']},
];
// For each iteration pass in the accumulator
// and the current object
const out = arr.reduce((acc, c) => {
// Assign the value of `a` to `key`
const key = c.a;
// If the key doesn't exist on the accumulator
// set a new object
acc[key] = acc[key] || { a: key, b: [] };
// And then push the first element of `b`
// into the object's array
acc[key].b.push(c.b[0]);
// Return the accumulator
return acc;
}, {});
// And then finally get the Object.values from
// your returned object to make an array
console.log(Object.values(out));
You can use reduce for that
First you create an object with the value of a as key and you group all b with the same a
Then you simply remove the object keys using Object.values
const array = [
{a: 1, b: ['Foo']},
{a: 1, b: ['Bar']},
{a: 1, b: ['Baz']},
{a: 2, b: ['Foo']},
{a: 3, b: ['Foo']},
]
const grouped = Object.values(array.reduce(
(res, {a, b}) => {
const existing = res[a] || {b: []}
return {
...res,
[a]: {a, b: [...existing.b, ...b]}
}
}, {}
))
console.log(grouped)
Using reduce you can merge the values of b and create a new array.
const array = [
{a: 1, b: ['Foo']},
{a: 1, b: ['Bar']},
{a: 1, b: ['Baz']},
{a: 2, b: ['Foo']},
{a: 3, b: ['Foo']},
];
const result = array.reduce((t, { a, b }, _, arr) => {
if (t.some(v => v.a === a))
return t; // if a is already handled, skip
return [
...t,
{
a,
b: arr
.filter(v => v.a === a) // filter out items with different "a" value
.reduce((t, v) => [...t, ...v.b], []), // merge the values of "b"
}
];
}, []);
console.log(result);