Skip to content Skip to sidebar Skip to footer

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)"