最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Union of 2 arrays using lodash - Stack Overflow

matteradmin4PV0评论

I have the following 2 arrays:

    arr1 = [
            {
                "key1": "Value1"
            },
            {
                "key2": "Value2"
            },
            {
                "key3": "Test3"
            },
            {
                "key4": "Test4"
            },
            {
                "key5": "Test5"
            },
            {
                "key6": "Test6"
            },
            {
                "key7": "Test7"
            }
        ]

And the second array is

    arr2 = [
            {
                "key3": "Value3-changed"
            },
            {
                "key6": "Value6-changed"
            }

        ]

Now once I join the 2 arrays the result would be

   resultArr = [
        {
            "key1": "Value1"
        },
        {
            "key2": "Value2"
        },
        {
            "key3": "Value3-changed"
        },
        {
            "key4": "Test4"
        },
        {
            "key5": "Test5"
        },
        {
            "key6": "Value6-changed"
        },
        {
            "key7": "Test7"
        }
    ]

I saw the solution for Lodash union of arrays of objects. But as for my case, the keys are different. Any, pointers on solving this issue? I was trying to use lodash _.unionBy and then _.uniqWith but not getting the desired result.

Thanks, Andy

I have the following 2 arrays:

    arr1 = [
            {
                "key1": "Value1"
            },
            {
                "key2": "Value2"
            },
            {
                "key3": "Test3"
            },
            {
                "key4": "Test4"
            },
            {
                "key5": "Test5"
            },
            {
                "key6": "Test6"
            },
            {
                "key7": "Test7"
            }
        ]

And the second array is

    arr2 = [
            {
                "key3": "Value3-changed"
            },
            {
                "key6": "Value6-changed"
            }

        ]

Now once I join the 2 arrays the result would be

   resultArr = [
        {
            "key1": "Value1"
        },
        {
            "key2": "Value2"
        },
        {
            "key3": "Value3-changed"
        },
        {
            "key4": "Test4"
        },
        {
            "key5": "Test5"
        },
        {
            "key6": "Value6-changed"
        },
        {
            "key7": "Test7"
        }
    ]

I saw the solution for Lodash union of arrays of objects. But as for my case, the keys are different. Any, pointers on solving this issue? I was trying to use lodash _.unionBy and then _.uniqWith but not getting the desired result.

Thanks, Andy

Share Improve this question asked Mar 27, 2018 at 16:01 AnirbanAnirban 5893 gold badges17 silver badges40 bronze badges 5
  • Can you copy the code into a snippet so we can see where it might have gone wrong? – Nope Commented Mar 27, 2018 at 16:02
  • Why does this need to be an array? – Explosion Pills Commented Mar 27, 2018 at 16:02
  • Without lodash, you can concat 2 arrays, and the remove duplicates element if you need the union semantics. See for instance : stackoverflow./questions/1584370/… – Pac0 Commented Mar 27, 2018 at 16:04
  • 1 Possible duplicate of How to merge two array of object by using lodash? – Mr. Polywhirl Commented Mar 27, 2018 at 16:25
  • also possible duplicate : lodash - Union of arrays of objects – Pac0 Commented Mar 27, 2018 at 16:28
Add a ment  | 

6 Answers 6

Reset to default 2

No lodash needed. First reduce both arrays to a single object, where keys ing later overwrite any previously set values:

const obj = [...arr1, ...arr2].reduce((acc,cur) => Object.assign(acc, cur), {});
// {key1: value1, ...}

Edit, even simpler:

const obj = Object.assign({}, ...arr1, ...arr2);

Then map the keys back to an array of objects:

const resultArray = Object.keys(obj)
   .sort() // if alphanumeric order of keys matters to you
   .map(key => { const o={}; o[key]=obj[key]; return o;});

You can do this without lodash like this :

(pushes new objects, or update existing one.

let arr1 = [
    {
        "key1": "Value1"
    },
    {
        "key2": "Value2"
    },
    {
        "key3": "Test3"
    },
    {
        "key4": "Test4"
    },
    {
        "key5": "Test5"
    },
    {
        "key6": "Test6"
    },
    {
        "key7": "Test7"
    },
]

let arr2 = [
    {
        "key3": "Value3-changed"
    },
    {
        "key6": "Value6-changed"
    },
    {
        "key10": "Value10-new"
    },
]

for (let obj of arr2) {
    let keyName = Object.keys(obj)[0];
    let existingObject = arr1.find(x => Object.keys(x)[0] === keyName );
    
    if (existingObject) {
        // object with same key exists. So we update it.
        existingObject[keyName] = obj[keyName];
    } else {
        // key was not found, this is a new object, let's add it.
        arr1.push(obj);
    }
}

console.log(arr1)

There is probably a more elegant way to do that, of course.

If you have access to the ... spread operator:

map(chunk(toPairs(assign(...arr1, ...arr2))), fromPairs)

Otherwise:

map(chunk(toPairs(spread(assign)(concat(arr1, arr2)))), fromPairs)

Which is ugly but does the job.


Lodash plugins

_.mixin({
  'assignPairsChunkAndMapObjects' : function(arr1, arr2) {
    return _.map(_.chunk(_.toPairs(_.assign(...arr1, ...arr2))), _.fromPairs);
  },
  'assignPairsChunkAndMapObjectsChained' : function(arr1, arr2) {
    return _.chain(_.assign(...arr1, ...arr2)).toPairs().chunk().map(_.fromPairs).value();
  }
});

With native javascript you can achieve the same using for ..in & map function

var arr1 = [{
    "key1": "Value1"
  },
  {
    "key2": "Value2"
  },
  {
    "key3": "Test3"
  },
  {
    "key4": "Test4"
  },
  {
    "key5": "Test5"
  },
  {
    "key6": "Test6"
  },
  {
    "key7": "Test7"
  }
]
var arr2 = [{
    "key3": "Value3-changed"
  },
  {
    "key6": "Value6-changed"
  }

];
// get object keys from both
var getArr2Keys = arr2.map(function(items) {
  for (let keys in items) {
    return keys;
  }
});

var getArr1Keys = arr1.map(function(items) {
  for (let keys in items) {
    return keys;
  }
});


// iterate over the newly created object and check if the key matched
getArr2Keys.forEach(function(itemArr2, index) {
  var x = getArr1Keys.findIndex(function(itemArr1) {
    return itemArr2 === itemArr1;
  })
  // replace the key value of arr1 with value from arr2
  arr1[x][itemArr2] = arr2[index][itemArr2]

})

console.log(arr1)

You can create a mixin to iterate over the first array and merge it with the second one.

_.mixin({
  'mergeObjectList' : function(arr1, arr2) {
    return _.map(arr1, function(obj) {
      Object.keys(obj).forEach(key => {
        var found = _.find(arr2, x => Object.keys(x).indexOf(key) > -1);
        if (found != null) {
          return _.merge(obj, found);
        }
      });
      return obj;
    });
  }
});

var arr1 = [
  { "key1": "Value1" },
  { "key2": "Value2" },
  { "key3": "Test3" },
  { "key4": "Test4" },
  { "key5": "Test5" },
  { "key6": "Test6" },
  { "key7": "Test7" }
];

var arr2 = [
  { "key3": "Value3-changed" },
  { "key6": "Value6-changed" }
];

var arr3 = _.mergeObjectList(arr1, arr2);

document.body.innerHTML = JSON.stringify(arr3, null, 4);
body { font-family: monospace; white-space: pre; }
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

You can also use map and find method of array.

In ES5

var arr1 = [{
    "key1": "Value1"
  }, {
    "key2": "Value2"
  }, {
    "key3": "Test3"
  }, {
    "key4": "Test4"
  }, {
    "key5": "Test5"
  }, {
    "key6": "Test6"
  }, {
    "key7": "Test7"
  }],

  arr2 = [{
    "key3": "Value3-changed"
  }, {
    "key6": "Value6-changed"
  }],

  key = '';

var result = arr1.map(function(item) {
  key = Object.keys(item)[0];
  return arr2.find(function(v) {
    return v[key]
  }) || item;
});

console.log(result);

In ES6

const arr1 = [{
    "key1": "Value1"
  }, {
    "key2": "Value2"
  }, {
    "key3": "Test3"
  }, {
    "key4": "Test4"
  }, {
    "key5": "Test5"
  }, {
    "key6": "Test6"
  }, {
    "key7": "Test7"
  }],

  arr2 = [{
      "key3": "Value3-changed"
    }, {
      "key6": "Value6-changed"
    }

  ];

let result = arr1.map(item => {
  let key = Object.keys(item)[0];
  return arr2.find(v => v[key]) || item;
});

console.log(result);

Post a comment

comment list (0)

  1. No comments so far