如何根据匹配的索引更新一个数组到另一个数组?

11
我有以下两个对象数组。我想要更新array1元素以反映匹配transid的array2元素。因此,我的结果应该是一个新的数组,其中包含已更新为反映array2中值的两个元素,或者是具有更新值的相同array1。
使用一些现代语法,什么是最好的方法?我打开几个选项,以便进行比较。例如,我猜测可以用array2对象替换array1中匹配的对象,或者通过对元素进行迭代来更新array1对象中的单个元素。
var arra1 = [{
    "_id" : ObjectId("583f6e6d14c8042dd7c979e6"),
    "transid" : 1,
    "acct" : "acct1",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category1",
    "amount" : 103 
}, {
    "_id" : ObjectId("583f6e6d14c8042dd7c2132t6"),
    "transid" : 2,
    "acct" : "acct2",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category2",
    "amount" : 103 
}]

var arra2 = [{
    "_id" : ObjectId("583f6e6d14c8042dd7c979e6"),
    "transid" : 1,
    "acct" : "acct2",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category5",
    "amount" : 107 
}, {
    "_id" : ObjectId("583f6e6d14c8042dd7c2132t6"),
    "transid" : 2,
    "acct" : "acct2",
    "transdate" : ISODate("2012-01-31T05:00:00.000Z"),
    "category" : "category2",
    "amount" : 103 
}, {
    "_id" : ObjectId("583f6e6d14c8042dd7c2132t6"),
    "transid" : 3,
    "acct" : "acct2",
    "transdate" : ISODate("2016-07-31T05:00:00.000Z"),
    "category" : "category3",
    "amount" : 103 
}]

我已经尝试过一些操作,目前大致有以下结果。虽然还没有成功,但这就是我想要的逻辑。

arr1.forEach(item => 
  if (arr2.indexOf(item.transid) != -1){
    item.category = arr2.indexOf(item.transid).category
  }
)

现代是指ES6吗?这意味着不用担心在所有浏览器上的兼容性问题吗? - Matt
是的,我使用ES6。为了本地开发和学习目的,我使用babel也可以。但是,为了更好的兼容性,我也愿意接受任何非ES6的解决方案。 - mo_maat
在任何一个数组中是否有重复的 transid 的可能性?意思是每个数组中只有0或1个transid。如果第二个数组可能有3个transid 1,则会消除一些选项。 - Matt
不要有任何数组中的重复项。我编辑了我的帖子,以添加我正在尝试设置的一小段逻辑。 - mo_maat
3个回答

29
arra1 = arra1.map(item => {
  const item2 = arra2.find(i2 => i2.transid === item.transid);
  return item2 ? { ...item, ...item2 } : item;
});

arra1中的所有元素映射到arra1本身。在映射函数中,尝试在arra2中找到相关项,并使用对象拓展将两个项合并(如果找到了),否则返回原始项。请注意,在合并时最后展开item2是至关重要的,因此您会用来自item2的值覆盖item1中的值,并保留未被覆盖的item1的值。


1
我爱你,伙计。 - Diego

6
你应该使用方法find来检索匹配项。
arr1.forEach(item1 => {
      var itemFromArr2 = arr2.find(item2 => item2.transid == item1.transid);

      if (itemFromArr2) {
         item1.category = itemFromArr2.category;
      }
   }
)

5
请使用reduce来完成这个任务。
let res = arr2.reduce((a,b) => {
    let a1 = arr1.find(e => e.transid === b.transid) || {};
    return a.concat(Object.assign(a1, b));
},[]);

console.log(res);

let arr1 = [{
  "_id": ObjectId("583f6e6d14c8042dd7c979e6"),
  "transid": 1,
  "acct": "acct1",
  "transdate": ISODate("2012-01-31T05:00:00.000Z"),
  "category": "category1",
  "amount": 103
}, {
  "_id": ObjectId("583f6e6d14c8042dd7c2132t6"),
  "transid": 2,
  "acct": "acct2",
  "transdate": ISODate("2012-01-31T05:00:00.000Z"),
  "category": "category2",
  "amount": 103
}]

let arr2 = [{
  "_id": ObjectId("583f6e6d14c8042dd7c979e6"),
  "transid": 1,
  "acct": "acct2",
  "transdate": ISODate("2012-01-31T05:00:00.000Z"),
  "category": "category5",
  "amount": 107
}, {
  "_id": ObjectId("583f6e6d14c8042dd7c2132t6"),
  "transid": 2,
  "acct": "acct2",
  "transdate": ISODate("2012-01-31T05:00:00.000Z"),
  "category": "category2",
  "amount": 103
}, {
  "_id": ObjectId("583f6e6d14c8042dd7c2132t6"),
  "transid": 3,
  "acct": "acct2",
  "transdate": ISODate("2016-07-31T05:00:00.000Z"),
  "category": "category3",
  "amount": 103
}]
// MOCK
function ObjectId(i) {
  return i;
}

function ISODate(i) {
  return i;
}
//
let res = arr2.reduce((a, b) => {
  let a1 = arr1.find(e => e.transid === b.transid) || {};
  return a.concat(Object.assign(a1, b));
}, []);

console.log(res);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接