Reputation: 643
Here is my simple array of objects
const array = [
{ name: 'a', val: '1234' },
{ name: 'b', val: '5678' },
{ name: 'c', val: '91011' },
{ name: 'c', val: '123536' },
{ name: 'e', val: '5248478' },
{ name: 'c', val: '5455' },
{ name: 'a', val: '548566' },
{ name: 'a', val: '54555' }
]
I need to group consecutive name elements and push the corresponding val
. So the expected output should be
const array = [
{ name: 'a', vals: '1234' },
{ name: 'b', vals: '5678' },
{ name: 'c', vals: ['91011', '123536'] },
{ name: 'e', vals: '5248478' },
{ name: 'c', vals: '5455' },
{ name: 'a', vals: ['548566', '54555'] }
]
I tried it But could not get over it. Please help
const output = []
const result = array.reduce((a, c) => {
if (a.name === c.name) {
output.push(a);
}
}, []);
Upvotes: 0
Views: 309
Reputation: 138277
You were actually quite close:
const output = [];
array.reduce((a, c) => {
if (a.name === c.name) { // current element equals previous element, lets merge
a.values.push(c.val);
} else output.push(a = { name: c.name, values: [c.val] ); // otherwise add new entry
return a; // the current element is the next previous
} , {}); // start with an empty a, so that c always gets pushed
Note that it makes little sense to store numbers as string though.
Upvotes: 2
Reputation: 35222
You can reduce
the array like this. Compare the current name
with previous item's name. If they are not the same, add a new item to the accumulator. If they are the same, then use concat
the merge val
with the last item in accumulator. concat
is used because vals
could either be a string or an array.
const array = [
{ name: 'a', val: '1234' },
{ name: 'b', val: '5678' },
{ name: 'c', val: '91011' },
{ name: 'c', val: '123536' },
{ name: 'e', val: '5248478' },
{ name: 'c', val: '5455' },
{ name: 'a', val: '548566' },
{ name: 'a', val: '54555' }
]
const merged = array.reduce((acc, { name, val }, i, arr) => {
// check if name is same as the previous name
if (arr[i - 1] && arr[i - 1].name === name) {
const prev = acc[acc.length - 1]; // last item in the accumulator
prev.vals = [].concat(prev.vals, val)
} else
acc.push({ name, vals: val })
return acc
}, [])
console.log(merged)
Upvotes: 1