Search code examples
lodash

Lodash and merge of Arrays with Key


I am able to merge objects stored in array fine with lodash but what I need is the find a way to merge based on a key which is part of the object. If I don't use key, the merge is not reliable as when a doc is returned out of order, as it will create an invalid merge. So I hope that there is a way to merge based on a key value, in my case its id.

Here is some sample:

Doc 1

[
    {
         "id": 123,
         "Key1": "Test 1",
         "Key3": "Test 0"
    },
    {
         "id": 456,
         "Key1": "Test 2",
         "Key2": "Test 3"
    }
]

Doc 2

[

    {
         "id": 123,
         "Key2": "Test 7",
         "Key3": "Test 8"
    },
    {
         "id": 789,
         "Key1": "Test 5",
         "Key2": "Test 6"
    }
]

Based on the simple sample above i am looking for an output like this

[
    {
         "id": 123,
         "Key1": "Test 1",
         "Key2": "Test 7",
         "Key3": "Test 8"
    },
    {
         "id": 456,
         "Key1": "Test 2",
         "Key2": "Test 3"
    },
    {
         "id": 789,
         "Key1": "Test 5",
         "Key2": "Test 6"
    }
]

Solution

  • const addKeys = (results, keys) => keys.reduce(
      (final, item) => {
        const id = item.id;
        let current = final.find(i => i.id === id);
        if (!current) {
          current = { id: id };
          final.push(current);
        }
        Object.keys(item).forEach(key => { current[key] = item[key] });
        return final;
      }, results
    );
    
    console.log(addKeys(
      [
          {
               "id": 123,
               "Key1": "Test 1",
               "Key3": "Test 0"
          },
          {
               "id": 456,
               "Key1": "Test 2",
               "Key2": "Test 3"
          }
      ],
      [
    
          {
               "id": 123,
               "Key2": "Test 7",
               "Key3": "Test 8"
          },
          {
               "id": 789,
               "Key1": "Test 5",
               "Key2": "Test 6"
          }
      ]
    ));