Merge Partially Duplicated Arrays In Javascript (lodash)
I have a large javascript array of some people Bought a car in different years. the simplified array is like this: const owners = [{ name: 'john', hasCar: true, yearBought: 2
Solution 1:
You could use reduce
the array and group them based on name
first. The accumulator is an object with each unique name
as key. If the name
already exists, use concat
to push them into the array. Else, create a new key in the accumulator and set it to the current object. Then, use Object.values()
to get the values of the array as an array
const owners = [{name:"john",hasCar:!0,yearBought:2002},{name:"john",hasCar:!0,yearBought:2005},{name:"mary",hasCar:!0,yearBought:2015},{name:"john",hasCar:!0,yearBought:2018}];
const merged = owners.reduce((r, o) => {
if(r[o.name])
r[o.name].yearBought = [].concat(r[o.name].yearBought, o.yearBought)
else
r[o.name] = { ...o };
return r;
},{})
console.log(Object.values(merged))
Solution 2:
Just use reduce
:
const owners = [{name:"john",hasCar:true,yearBought:2002},{name:"john",hasCar:true,yearBought:2005},{name:"mary",hasCar:true,yearBought:2015},{name:"john",hasCar:true,yearBought:2018}];
const newOwners = Object.values(owners.reduce((acc, curr) => {
acc[curr.name] = acc[curr.name] ? { ...acc[curr.name], yearBought: [].concat(acc[curr.name].yearBought, curr.yearBought) } : curr;
return acc;
}, {}));
console.log(newOwners);
Solution 3:
I hope this help using PURE lodash functions.. it looks clean and readable.
var array = [{
name: "john",
hasCar: true,
yearBought: 2002
}, {
name: "john",
hasCar: true,
yearBought: 2005
}, {
name: "mary",
hasCar: true,
yearBought: 2015
}, {
name: "john",
hasCar: true,
yearBought: 2018
}]
functionmergeNames(arr) {
returnObject.values(_.chain(arr).groupBy('name').mapValues((g) => (_.merge(...g, {
yearBought: _.map(g, 'yearBought')
}))).value());
}
console.log(mergeNames(array));
<scriptsrc="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
Thanks :)
Solution 4:
You can group the items with a unique key (name
in your case), then map the groups, and merge the items in each group:
const { flow, partialRight: pr, groupBy, map, mergeWith, concat, isUndefined } = _
constmergeDuplicates = (isCollected, key) => flow(
pr(groupBy, key), // group by the unique keypr(map, group =>mergeWith({}, ...group,
(o, s, k) =>isCollected(k) && !isUndefined(o) ? concat(o, s) : s
)) // merge each group to a new object
)
const owners = [{name:"john",hasCar:true,yearBought:2002},{name:"john",hasCar:true,yearBought:2005},{name:"mary",hasCar:!0,yearBought:2015},{name:"john",hasCar:true,yearBought:2018}]
constisCollected = key => key === 'yearBought'const result = mergeDuplicates(isCollected, 'name')(owners)
console.log(result)
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
And the lodash/fp version:
const { flow, groupBy, map, mergeAllWith, cond, nthArg, concat } = _
constmergeDuplicates = (isCollected, key) => flow(
groupBy(key),
map(mergeAllWith(cond([[
flow(nthArg(2), isCollected),
concat,
nthArg(1)
]])))
)
const owners = [{name:"john",hasCar:!0,yearBought:2002},{name:"john",hasCar:!0,yearBought:2005},{name:"mary",hasCar:!0,yearBought:2015},{name:"john",hasCar:!0,yearBought:2018}]
constisCollected = key => key === 'yearBought'const result = mergeDuplicates(isCollected, 'name')(owners)
console.log(result)
<scriptsrc='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
Post a Comment for "Merge Partially Duplicated Arrays In Javascript (lodash)"