简体   繁体   中英

Merge property from an array of objects into another based on property value lodash

I have 2 arrays of objects, they each have an id<\/code> in common. I need a property from objects of array 2 added to objects array 1, if they have matching id<\/code> s.

[
    {
        id: 1,
        name: tom,
        age: 24
    },
    {
        id: 2,
        name: tim,
        age: 25
    },
    {
        id: 3,
        name: jack,
        age: 24
    },

]

Lodash remains a highly useful bag of utilities, but with the advent of ES6 some of its use cases are less compelling.

For each object (person) in the first array, find the object in the second array with matching ID (see function findPerson ). Then merge the two.

function update(array1, array2) {
  var findPerson = id => array2.find(person => person.id === id);

  array1.forEach(person => Object.assign(person, findPerson(person.id));
}

For non-ES6 environments, rewrite arrow functions using traditional syntax. If Array#find is not available, write your own or use some equivalent. For Object.assign , if you prefer use your own equivalent such as _.extend .

This will merge all properties from array2 into array1 . To only merge eyeColour :

function update(array1, array2) {
  var findPerson = id => array2.find(person => person.id === id);

  array1.forEach(person => {
    var person2 = findPerson(person.id));
    var {eyeColour} = person2;
    Object.assign(person, {eyeColour});
  });
}

Just noticed Paul answered while I was working on my answer but I'll add my very similar code anyway:

var getEyeColour = function (el) { return _.pick(el, 'eyeColour'); }
var out = _.merge(arr1, _.map(arr2, getEyeColour));

DEMO

You can use pick to get only the properties you want before merging:

var result = _.merge( arr1, _.map( arr2, function( obj ) {
    return _.pick( obj, 'id', 'eyeColour' );
}));

A solution in plain Javascript

This is a more generic solution for merging two arrays which have different properties to union in one object with a common key and some properties to add.

 var array1 = [{ id: 1, name: 'tom', age: 24 }, { id: 2, name: 'tim', age: 25 }, { id: 3, name: 'jack', age: 24 }, ], array2 = [{ id: 1, gender: 'male', eyeColour: 'blue', weight: 150 }, { id: 2, gender: 'male', eyeColour: 'green', weight: 175 }, { id: 3, gender: 'male', eyeColour: 'hazel', weight: 200 }, ]; function merge(a, b, id, keys) { var array = [], object = {}; function m(c) { if (!object[c[id]]) { object[c[id]] = {}; object[c[id]][id] = c[id]; array.push(object[c[id]]); } keys.forEach(function (k) { if (k in c) { object[c[id]][k] = c[k]; } }); } a.forEach(m); b.forEach(m); return array; } document.write('<pre>' + JSON.stringify(merge(array1, array2, 'id', ['name', 'age', 'eyeColour']), 0, 4) + '</pre>'); 

I was looking for the same, but I want to match Id before merging

var out = arr1.map(x => {
    return  { ...x, eyeColour:  arr2.find(y => x.id === y.id)?.eyeColour }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM