替换数组中的对象

IT技术 javascript lodash
2021-03-11 09:53:20

我有这个 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'}]

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

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

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

如何使用javascript实现它?

6个回答

您可以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);

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

@Michael 不,它只能在最新的浏览器中工作。您可以查看规范,对于较旧的浏览器,请使用polyfill
2021-04-20 09:53:20
@JavaBanana 你有什么建议?
2021-04-20 09:53:20
如果还包含 ES5 语法,那就太好了。
2021-05-09 09:53:20
有时我们会遇到非常有指导意义和有用的代码;这是其中之一。谢谢
2021-05-11 09:53:20
这是实现目标的一种非常低效的方式,因为 find 方法每次调用时都会迭代整个数组。
2021-05-15 09:53:20

怎么了Object.assign(target, source)

在此处输入图片说明

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

不适用于 Internet Explorer 11。不过有一个 polyfill:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-23 09:53:20

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

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

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>

关于时间与空间的争论总是会发生,但是现在我发现从长远来看,使用空间更好.. 撇开数学不谈,让我们看看使用哈希图、字典或关联的一种实用方法来解决这个问题数组是你想要标记简单数据结构的任何东西。

    var marr2 = new Map(arr2.map(e => [e.id, e]));
    arr1.map(obj => marr2.has(obj.id) ? marr2.get(obj.id) : obj);

我喜欢这种方法,因为尽管您可以与低数字的数组争论,但您正在浪费空间,因为像 @Tushar 方法这样的内联方法与这种方法的表现非常接近。但是,我进行了一些测试,图表显示了两种方法在 n 0 - 1000 之间的性能如何。您可以根据自己的情况决定哪种方法最适合您,但根据我的经验,用户不太关心小空间,但是他们确实关心小速度。


绩效衡量


这是我为数据源运行的性能测试

var n = 1000;
var graph = new Array();
for( var x = 0; x < n; x++){
  var arr1s = [...Array(x).keys()];
  var arr2s = arr1s.filter( e => Math.random() > .5);
  var arr1 = arr1s.map(e => {return {id: e, name: 'bill'}});
  var arr2 = arr2s.map(e => {return {id: e, name: 'larry'}});
  // Map 1
  performance.mark('p1s');
  var marr2 = new Map(arr2.map(e => [e.id, e]));
  arr1.map(obj => marr2.has(obj.id) ? marr2.get(obj.id) : obj);
  performance.mark('p1e');
  // Map 2
  performance.mark('p2s');
  arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);
  performance.mark('p2e');
  graph.push({ x: x, r1: performance.measure('HashMap Method', 'p1s', 'p1e').duration, r2: performance.measure('Inner Find', 'p2s','p2e').duration});
}

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

  1. 合并 2 个实体数组

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

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

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

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

它将同一种类型的数组与某种类型合并

示例:人员数组 ->

[{id:1, name:"Bir"},{id:2, name: "Iki"},{id:3, name:"Uc"}]   
second param Person {id:3, name: "Name changed"}   

结果是

[{id:1, name:"Bir"},{id:2, name: "Iki"},{id:3, name:"Name changed"}]