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

假装没事ソ 提交于 2019-12-28 19:35:31

问题


I have 2 arrays of objects, they each have an id in common. I need a property from objects of array 2 added to objects array 1, if they have matching ids.

Array 1:

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

]

Array 2:

[
    {
        id: 1,
        gender: male,
        eyeColour: blue,
        weight: 150
    },
    {
        id: 2,
        gender: male,
        eyeColour: green,
        weight: 175
    },
    {
        id: 3,
        gender: male,
        eyeColour: hazel,
        weight: 200
    },

]

Desired Outcome:

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

]

I tried using lodash _.merge function but then I end up with all properties into one array, when I only want eyeColour added.


回答1:


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




回答2:


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});
  });
}



回答3:


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' );
}));



回答4:


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>');


来源:https://stackoverflow.com/questions/34795049/merge-property-from-an-array-of-objects-into-another-based-on-property-value-lod

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!