1

I am finding a difficult time finding a solution for multiple levels of push / merging with Lodash and Underscore. Trying to avoid some messy nested loops with JS.

Here's an example of how I need to merge.

const arr = [
  {
    level : 'test',
    items : [1, 2, 3]
  },
  {
    level : 'tests',
    items : [1, 2, 3]
  }
];

const obj = {
  level : 'test',
  items : [4, 5, 6]
};


/* Output:
  [
    {
      level : 'test',
      items : [1, 2, 3, 4, 5, 6]
    },
    {
      level : 'tests',
      items : [1, 2, 3]
    }
  ];
*/

The obj level matches arr[0], and so the items array should merge. New, or unique levels should push to the array as a new object.

Is there a way I could achieve this through some combination of _.groupBy and _.mergeWith of Lodash? So far, I have gotten it to merge into a single array with two objects from the two respective unique levels, but when the items arrays merge it ends up with [4, 5, 6].

Any help would be appreciated.

JSess
  • 638
  • 4
  • 13
  • Possible duplicate of [Merge javascript objects in array with same key](https://stackoverflow.com/questions/33850412/merge-javascript-objects-in-array-with-same-key) – Heretic Monkey Mar 07 '18 at 18:30

3 Answers3

2

You can use array#find to search for an object with same level value. Then, for a successful match array#concat items.

const arr = [ { level : 'test', items : [1, 2, 3] }, { level : 'tests', items : [1, 2, 3] } ]; 
const obj = { level : 'test', items : [4, 5, 6] };
const result = arr.find(o => o.level === obj.level);
if(result)
  result.items = result.items.concat(obj.items);
console.log(arr);
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
1

const arr = [
  {
    level : 'test',
    items : [1, 2, 3]
  },
  {
    level : 'tests',
    items : [1, 2, 3]
  }
];

const obj = {
  level : 'test',
  items : [4, 5, 6]
};


/* Output:
  [
    {
      level : 'test',
      items : [1, 2, 3, 4, 5, 6]
    },
    {
      level : 'tests',
      items : [1, 2, 3]
    }
  ];
*/

const newArr = _.map(arr, (val) => {
  return !_.isEqual(val.level, obj.level) ? val 
    : _.assign({}, val, {
      items: _.concat(val.items, obj.items)
    });
});

console.log(newArr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
th3n3wguy
  • 3,649
  • 2
  • 23
  • 30
  • This doesn't appear to function. I've accepted another answer, so thank you for your help anyway th3n3wguy – JSess Mar 07 '18 at 19:35
  • @JSess => I updated the code because I was missing the external library and a closing bracket. – th3n3wguy Mar 07 '18 at 21:06
  • The main difference between my answer and your accepted answer is that mine is using Lodash, which is what you originally asked for. Lol. – th3n3wguy Mar 08 '18 at 23:50
  • I know, but I implemented his first and it worked. I can't accept multiple answers or I would. I upvoted you, though. – JSess Mar 09 '18 at 00:53
  • 1
    @JSess => That is fully-understandable. I should've made sure that my code was 100% functional first. Either way, I am glad that you found a working answer. :) – th3n3wguy Mar 09 '18 at 14:19
1
arr.map((e)=>{e.level === obj.level && e.items.push(...obj.items);return e})

let me know if it works

Saikat Hajra
  • 670
  • 3
  • 12
  • 2
    This does work, but I have accepted the other answer already. I appreciate your help, Saikat Hajra. – JSess Mar 07 '18 at 19:35