Reputation: 4439
I have a array like this:
let obj = [
{
id: 1,
name: 'bob'
},
{
id: 2,
name: 'bob'
},
{
id: 3,
name: 'karl'
},
{
id: 4,
name: 'joe'
},
{
id: 5,
name: 'joe'
}, {
id: 6,
name: 'rick'
},
];
I need to write some javascript code to parse through the array and handle the duplicate names.
My desired outcome is:
let obj = [
{
id: [1,2],
name: 'bob'
},
{
id: 3,
name: 'karl'
},
{
id: [4,5],
name: 'joe'
},
{
id: 6,
name: 'rick'
},
];
Can anyone help?
Upvotes: 0
Views: 66
Reputation: 505
Array.prototype.reduce() is useful in this case.
let obj = [{
id: 1,
name: 'bob'
},
{
id: 2,
name: 'bob'
},
{
id: 3,
name: 'karl'
},
{
id: 4,
name: 'joe'
},
{
id: 5,
name: 'joe'
}, {
id: 6,
name: 'rick'
},
];
const mergeObjectByValue = (objArray) => {
const newObjs = objArray.reduce((prev, {
name,
id
}) => {
(name in prev) ? prev[name].push(id): prev[name] = [id]
return prev;
}, {})
return Object.entries(newObjs).map(([name, ids]) => ({
name,
id: ids.length > 1 ? ids : ids[0],
}))
}
console.log(mergeObjectByValue(obj))
Upvotes: 0
Reputation: 25408
You can easily achieve this result using reduce and find. If the existing element is an array
then you need to push it into array else create an array and push the existing element in the array along with new id
let obj = [
{
id: 1,
name: "bob",
},
{
id: 2,
name: "bob",
},
{
id: 3,
name: "karl",
},
{
id: 4,
name: "joe",
},
{
id: 5,
name: "joe",
},
{
id: 6,
name: "rick",
},
];
const result = obj.reduce((acc, curr) => {
const { id, name } = curr;
const findEl = acc.find((o) => o.name === name);
if (findEl) {
if (Array.isArray(findEl.id)) {
findEl.id.push(id);
} else {
findEl.id = [findEl.id, id];
}
} else {
acc.push({ id, name });
}
return acc;
}, []);
console.log(result);
You can improve its time complexity by introducing a dictionary and no need to find elements every time in reduce
. But here order can change of the object inside result
let obj = [
{
id: 1,
name: "bob",
},
{
id: 2,
name: "bob",
},
{
id: 3,
name: "karl",
},
{
id: 4,
name: "joe",
},
{
id: 5,
name: "joe",
},
{
id: 6,
name: "rick",
},
];
const dict = {};
obj.forEach((obj) => {
const { id, name } = obj;
if (dict[name]) {
if (Array.isArray(dict[name])) {
dict[name].push(id);
} else {
dict[name] = [dict[name], id];
}
} else {
dict[name] = id;
}
});
const result = Object.entries(dict).map(([name, id]) => ({ name, id }));
console.log(result);
Upvotes: 2