mo_maat
mo_maat

Reputation: 2240

How can I update an array based on another array on matching index?

I have the following two object arrays. I would like to update array1 elements to reflect array2 elements where the transid matches. So my result should be either a new array that has the two elements from array1 updated to reflect the values in array2, or the same array1 with the updated values.

What is the best way to do that with some of the more modern syntax? I open to several options so I can compare. For example, I'm guessing matching objects in array1 can just be replaced with array2 objects or the individual elements within the array1 objects can be updated through some sort of iteration over the elements.

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 
}]

I played with it a bit and have something like this thus far. It's not working but that's the type of logic I'm looking for.

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

Upvotes: 12

Views: 26306

Answers (3)

Marco Scabbiolo
Marco Scabbiolo

Reputation: 7469

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

Map all elements in arra1 into arra1 itself. On the mapping function try to find the correlative item in arra2 and merge the two items with object spread if its found, if not, return the original item. Notice that spreading item2 last is crucial to the merge, so you overwrite with the values from item2 but keep those in item1 that were not overwritten.

Upvotes: 31

Olivier Boissé
Olivier Boissé

Reputation: 18173

You should use the method find to retrieve the matching item

arr1.forEach(item1 => {
      var itemFromArr2 = arr2.find(item2 => item2.transid == item1.transid);

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

Upvotes: 6

baao
baao

Reputation: 73281

Use reduce for this

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

Upvotes: 5

Related Questions