Merge Duplicate Objects in Array of Objects

Merge duplicate objects in array of objects

I would probably loop through with filter, keeping track of a map of objects I'd seen before, along these lines (edited to reflect your agreeing that yes, it makes sense to make (entry).data always an array):

var seen = {};
data = data.filter(function(entry) {
var previous;

// Have we seen this label before?
if (seen.hasOwnProperty(entry.label)) {
// Yes, grab it and add this data to it
previous = seen[entry.label];
previous.data.push(entry.data);

// Don't keep this entry, we've merged it into the previous one
return false;
}

// entry.data probably isn't an array; make it one for consistency
if (!Array.isArray(entry.data)) {
entry.data = [entry.data];
}

// Remember that we've seen it
seen[entry.label] = entry;

// Keep this one, we'll merge any others that match into it
return true;
});

In an ES6 environment, I'd use seen = new Map() rather than seen = {}.

Note: Array.isArray was defined by ES5, so some quite older browsers like IE8 won't have it. It can easily be shimmed/polyfilled, though:

if (!Array.isArray) {
Array.isArray = (function() {
var toString = Object.prototype.toString;
return function(a) {
return toString.call(a) === "[object Array]";
};
})();
}

Side note: I'd probably also always make entry.data an array, even if I didn't see two values for it, because consistent data structures are easier to deal with. I didn't do that above because your end result showed data being just a string when there was only one matching entry. (We've done that above now.)

Live example (ES5 version):

var data = [    {        label: "Book1",        data: "US edition"    },    {        label: "Book1",        data: "UK edition"    },    {        label: "Book2",        data: "CAN edition"    }];snippet.log("Before:");snippet.log(JSON.stringify(data, null, 2), "pre");var seen = {};data = data.filter(function(entry) {    var previous;
// Have we seen this label before? if (seen.hasOwnProperty(entry.label)) { // Yes, grab it and add this data to it previous = seen[entry.label]; previous.data.push(entry.data);
// Don't keep this entry, we've merged it into the previous one return false; }
// entry.data probably isn't an array; make it one for consistency if (!Array.isArray(entry.data)) { entry.data = [entry.data]; }
// Remember that we've seen it seen[entry.label] = entry;
// Keep this one, we'll merge any others that match into it return true;});snippet.log("After:");snippet.log(JSON.stringify(data, null, 2), "pre");
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --><script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

merge duplicate objects in an array and add additional property

You can use reduce to create a unique array that sets admin property to true for duplicate addresses as follows:

const addresses = [{name: 'Paul', id: 2}, {name: 'John', id: 1}, {name: 'John', id: 1}];
const result = addresses.reduce((acc, address) => { const dup = acc.find(addr => addr.id === address.id); if (dup) { dup.admin = true; return acc; } address.admin = false; return acc.concat(address);}, [])
console.log(result);

merge duplicate objects in an array and combine sub array of each object

I think, reduce() would do the job:

const accounts = [{"Id":103,"accountList":[{}]},{"Id":103,"accountList":[{"tokenId":"5aasdasdsdnjn3434nadd","featureId":2840}]},{"Id":112,"accountList":[{"tokenId":"5d30775bef4a722c38aefaaa","featureId":2877}]},{"Id":112,"accountList":[{"tokenId":"5d30775bef4a722c38aefccc","featureId":2856}]}];

const result = [...accounts
.reduce((r, o) => {
const record = r.get(o.Id)||{}
r.set(o.Id, {
Id: o.Id,
accountList: [
...(record.accountList||[]),
...o.accountList.filter(o =>
Object.keys(o).length != 0)
]
})
return r
}, new Map())
.values()]

console.log(result);
.as-console-wrapper {min-height: 100%}

How to merge duplicate object parent items in array?

const data = [
{ "_id": { "month": 5, "year": 2021 }, "total_price": 145111500, "total_quantity": 7 },
{ "_id": { "month": 6, "year": 2021 }, "total_price": 98386000, "total_quantity": 5 },
{ "_id": { "month": 6, "year": 2021 }, "total_price": 32500000, "total_quantity": 3 }
];

const res = [...
// iterate over the list
data.reduce((map, item) => {
// construct key from _id
const key = `${item._id.month}-${item._id.year}`;
// get prev map value of key if exists
const prev = map.get(key);
// update map, if prev not found, set value as item, or update it with the added values
map.set(
key,
!prev
? item
: { ...item, total_price: prev.total_price + item.total_price, total_quantity: prev.total_quantity + item.total_quantity }
);
return map;
}, new Map)
// return map values
.values()
];

console.log(res);


Related Topics



Leave a reply



Submit