Reputation: 71
I've been struggling figuring out this problem.
So basically, i have this data (dummy)
[
{ user_id: 1, balance: 50, job: 'programmer' },
{ user_id: 1, balance: 20, job: 'teacher' },
{ user_id: 1, balance: 15, job: 'doctor' },
{ user_id: 2, balance: 5, job: 'doctor' },
{ user_id: 2, balance: 20, job: 'teacher' },
{ user_id: 3, balance: 100, job: 'teacher' },
{ user_id: 3, balance: 35, job: 'accountant' },
{ user_id: 3, balance: 40, job: 'lawyer' }
{ user_id: 3, balance: 10, job: 'programmer' }
{ user_id: 4, balance: 45, job: 'lawyer' }
]
And i want to reduce / grouping the array to be like this
[
{ user_id: 1, data: [{ balance: 50, job: 'programmer' }, { balance: 20, job: 'teacher' }, { balance: 15, job: 'doctor' }] },
{ user_id: 2, data: [{ balance: 5, job: 'doctor' }, { balance: 20, job: 'teacher' }] },
{ user_id: 3, data: [{ balance: 100, job: 'teacher' }, { 3, balance: 35, job: 'accountant' }, { balance: 40, job: 'lawyer' }, { balance: 10, job: 'programmer' }] },
{ user_id: 4, data: [{ balance: 45, job: 'lawyer' }] }
]
I've been trying to do it using .reduce
array.reduce((acc, obj) => {
const value = obj['user_id'];
acc[value] = (acc[value] || []).concat(obj);
return acc;
});
But it returns not as i expected.
Please help.
Thank you so much.
Upvotes: 0
Views: 60
Reputation: 138267
You are quite close:
const hash = array.reduce((acc, obj) => {
const value = obj.user_id; // typo?
acc[value] = acc[value] || { user_id: obj.user_id, data: [] }; // initialize to an object
acc[value].data.push(obj);
return acc;
}, {}); // <- use a plain object as accumulator
const result = Object.values(hash); // turn back into array
Upvotes: 1
Reputation: 386604
You could take a Map
and only a part of the object for the result set.
var array = [{ user_id: 1, balance: 50, job: 'programmer' }, { user_id: 1, balance: 20, job: 'teacher' }, { user_id: 1, balance: 15, job: 'doctor' }, { user_id: 2, balance: 5, job: 'doctor' }, { user_id: 2, balance: 20, job: 'teacher' }, { user_id: 3, balance: 100, job: 'teacher' }, { user_id: 3, balance: 35, job: 'accountant' }, { user_id: 3, balance: 40, job: 'lawyer' }, { user_id: 3, balance: 10, job: 'programmer' }, { user_id: 4, balance: 45, job: 'lawyer' }],
result = Array.from(
array.reduce((m, { user_id, ...rest }) =>
m.set(user_id, [...(m.get(user_id) || []), rest]), new Map),
([user_id, data]) => ({ user_id, data })
);
console.log(result);
Upvotes: 2
Reputation: 37755
You can simply use Object
as your accumulator and user_id
as key and than add values accordingly
let arr =[{ user_id: 1, balance: 50, job: 'programmer' },{ user_id: 1, balance: 20, job: 'teacher' },{ user_id: 1, balance: 15, job: 'doctor' },{ user_id: 2, balance: 5, job: 'doctor' },{ user_id: 2, balance: 20, job: 'teacher' },{ user_id: 3, balance: 100, job: 'teacher' },{ user_id: 3, balance: 35, job: 'accountant' },{ user_id: 3, balance: 40, job: 'lawyer' },{ user_id: 3, balance: 10, job: 'programmer' },{ user_id: 4, balance: 45, job: 'lawyer' },]
let op = arr.reduce((acc,{user_id,...rest}) => {
acc[user_id] = acc[user_id] || {user_id,data:[]}
acc[user_id].data.push({...rest})
return acc;
},{});
console.log(Object.values(op))
Upvotes: 1