Javascript 替换数组中的对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37585309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:29:13  来源:igfitidea点击:

Replacing objects in array

javascriptlodash

提问by Michael

I have this javascript object:

我有这个 javascript 对象:

var arr1 = [{id:'124',name:'qqq'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'eee'},
           {id:'567',name:'rrr'}]

var arr2 = [{id:'124',name:'ttt'}, 
           {id:'45',name:'yyy'}]

I need to replace objects in arr1with items from arr2with same id.

我需要用arr2 中具有相同id 的项目替换arr1 中的对象。

So here is the result I want to get:

所以这是我想要得到的结果:

var arr1 = [{id:'124',name:'ttt'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'yyy'},
           {id:'567',name:'rrr'}]

How can I implement it using javascript?

如何使用javascript实现它?

回答by Tushar

You can use Array#mapwith Array#find.

您可以Array#mapArray#find.

arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

var arr1 = [{
    id: '124',
    name: 'qqq'
}, {
    id: '589',
    name: 'www'
}, {
    id: '45',
    name: 'eee'
}, {
    id: '567',
    name: 'rrr'
}];

var arr2 = [{
    id: '124',
    name: 'ttt'
}, {
    id: '45',
    name: 'yyy'
}];

var res = arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);

console.log(res);

Here, arr2.find(o => o.id === obj.id)will return the element i.e. object from arr2if the idis found in the arr2. If not, then the same element in arr1i.e. objis returned.

在这里,arr2.find(o => o.id === obj.id)从返回即对象的元素arr2,如果id被发现的arr2。如果不是,则返回arr1ie 中的相同元素obj

回答by Jonathan

What's wrong with Object.assign(target, source)?

怎么了Object.assign(target, source)

enter image description here

在此处输入图片说明

Arrays are still type object in Javascript, so using assign should still reassign any matching keys parsed by the operator as long as matching keys are found, right?

数组在 Javascript 中仍然是类型对象,因此只要找到匹配的键,使用assign 仍然应该重新分配运算符解析的任何匹配键,对吗?

回答by spwisner

I am only submitting this answer because people expressed concerns over browsers and maintaining the order of objects. I recognize that it is not the most efficient way to accomplish the goal.

我提交这个答案只是因为人们表达了对浏览器和维护对象顺序的担忧。我认识到这不是实现目标的最有效方法。

Having said this, I broke the problem down into two functions for readability.

话虽如此,为了可读性,我将问题分解为两个函数。

// The following function is used for each itertion in the function updateObjectsInArr
const newObjInInitialArr = function(initialArr, newObject) {
  let id = newObject.id;
  let newArr = [];
  for (let i = 0; i < initialArr.length; i++) {
    if (id === initialArr[i].id) {
      newArr.push(newObject);
    } else {
      newArr.push(initialArr[i]);
    }
  }
  return newArr;
};

const updateObjectsInArr = function(initialArr, newArr) {
    let finalUpdatedArr = initialArr;  
    for (let i = 0; i < newArr.length; i++) {
      finalUpdatedArr = newObjInInitialArr(finalUpdatedArr, newArr[i]);
    }

    return finalUpdatedArr
}

const revisedArr = updateObjectsInArr(arr1, arr2);

jsfiddle

提琴手

回答by Musa

Thanks to ES6 we can made it with easy way -> for example on util.js module ;))).

感谢 ES6,我们可以用简单的方法实现它 -> 例如在 util.js 模块上 ;)))。

  1. Merge 2 array of entity

    export const mergeArrays = (arr1, arr2) => arr1 && arr1.map(obj => arr2 && arr2.find(p => p.id === obj.id) || obj);

  1. 合并 2 个实体数组

    export const mergeArrays = (arr1, arr2) => arr1 && arr1.map(obj => arr2 && arr2.find(p => p.id === obj.id) || obj);

gets 2 array and merges it.. Arr1 is main array which is priority is high on merge process

获取 2 个数组并合并它.. Arr1 是主数组,它在合并过程中优先级高

  1. Merge array with same type of entity

    export const mergeArrayWithObject = (arr, obj) => arr && arr.map(t => t.id === obj.id ? obj : t);

  1. 合并具有相同类型实体的数组

    export const mergeArrayWithObject = (arr, obj) => arr && arr.map(t => t.id === obj.id ? obj : t);

it merges same kind of array of type with some kind of type for example: array of person -> [{id:1, name:"Bir"},{id:2, name: "Iki"},{id:3, name:"Uc"}] second param Person {id:3, name: "Name changed"} result is [{id:1, name:"Bir"},{id:2, name: "Iki"},{id:3, name:"Name changed"}]

它将相同类型的数组与某种类型合并,例如:人数组 -> [{id:1, name:"Bir"},{id:2, name: "Iki"},{id:3 , name:"Uc"}] 第二个参数 Person {id:3, name: "Name changed"} 结果是 [{id:1, name:"Bir"},{id:2, name: "Iki"}, {id:3, name:"名称已更改"}]

回答by Dieterg

Since you're using Lodash you could use _.mapand _.findto make sure major browsers are supported.

由于您使用的是 Lodash,因此您可以使用_.map_.find确保支持主要浏览器。

In the end I would go with something like:

最后,我会选择类似的东西:

function mergeById(arr) {
  return {
    with: function(arr2) {
      return _.map(arr, item => {
        return _.find(arr2, obj => obj.id === item.id) || item
      })
    }
  }
}

var result = mergeById([{id:'124',name:'qqq'}, 
           {id:'589',name:'www'}, 
           {id:'45',name:'eee'},
           {id:'567',name:'rrr'}])
    .with([{id:'124',name:'ttt'}, {id:'45',name:'yyy'}])

console.log(result);
<script src="https://raw.githubusercontent.com/lodash/lodash/4.13.1/dist/lodash.js"></script>

回答by ryeballar

If you don't care about the order of the array, then you may want to get the difference between arr1and arr2by idusing differenceBy()and then simply use concat()to append all the updated objects.

如果你不关心排列的顺序,那么你可能想获得之间的差别arr1,并arr2通过id使用differenceBy() ,然后简单地使用CONCAT()追加所有更新的对象。

var result = _(arr1).differenceBy(arr2, 'id').concat(arr2).value();

var arr1 = [{
  id: '124',
  name: 'qqq'
}, {
  id: '589',
  name: 'www'
}, {
  id: '45',
  name: 'eee'
}, {
  id: '567',
  name: 'rrr'
}]

var arr2 = [{
  id: '124',
  name: 'ttt'
}, {
  id: '45',
  name: 'yyy'
}];

var result = _(arr1).differenceBy(arr2, 'id').concat(arr2).value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>

回答by ryeballar

function getMatch(elem) {
    function action(ele, val) {
        if(ele === val){ 
            elem = arr2[i]; 
        }
    }

    for (var i = 0; i < arr2.length; i++) {
        action(elem.id, Object.values(arr2[i])[0]);
    }
    return elem;
}

var modified = arr1.map(getMatch);

回答by daCoda

I went with this, because it makes sense to me. Comments added for readers!

我选择了这个,因为这对我来说很有意义。为读者添加评论!

masterData = [{id: 1, name: "aaaaaaaaaaa"}, 
        {id: 2, name: "Bill"},
        {id: 3, name: "ccccccccc"}];

updatedData = [{id: 3, name: "Cat"},
               {id: 1, name: "Apple"}];

updatedData.forEach(updatedObj=> {
       // For every updatedData object (dataObj), find the array index in masterData where the IDs match.
       let indexInMasterData = masterData.map(masterDataObj => masterDataObj.id).indexOf(updatedObj.id); // First make an array of IDs, to use indexOf().
       // If there is a matching ID (and thus an index), replace the existing object in masterData with the updatedData's object.
       if (indexInMasterData !== undefined) masterData.splice(indexInMasterData, 1, updatedObj);
});

/* masterData becomes [{id: 1, name: "Apple"}, 
                       {id: 2, name: "Bill"},
                       {id: 3, name: "Cat"}];  as you want.`*/