How to replace JS array property values using another JS array

Viewed 104

I want to replace JS array property values using another JS array. I have explained as below.

const arr1 = [
{
  code: "XXY",
  dis: "cont1",
  note: "Note for cont1"
}, 
{
  code: "AAW",
  dis: "cont2",
  note: "Note for cont2"
}, 
{
  code: "TTR",
  dis: "cont5",
  note: "Note for cont5"
}, 
{
  code: "MMN",
  dis: "cont10",
  note: "Note for cont10"
}]
const new_array = [
  {
    "code": "AAW",
    "dis": "cont2 new",
    "note": "Note for cont2"
  },
  {
    "code": "TTR",
    "dis": "cont5",
    "note": "New Note for cont5"
  }]

Expected output:

[
 {
  code: "XXY",
  dis: "cont1",
  note: "Note for cont1"
 }, 
 {
  code: "AAW",
  dis: "cont2 new",
  note: "Note for cont2"
 }, 
 {
  code: "TTR",
  dis: "cont5",
  note: "New Note for cont5"
 }, 
 {
  code: "MMN",
  dis: "cont10",
  note: "Note for cont10"
 }
]

We need to check all arr1 element where equal new_arr.code to arr1.code and compare dis and note properties. If arr1.dis not equals new_arr.dis then arr1.dis value should be replaced by new_arr.dis. This is same to note property also.

Tried code:

arr1.forEach(function(item1) {
        var item2 = arr1.find(function (item2) {
            return arr1.code === new_array.code;
        });
    })

console.log(arr1);

Current output:

[
  {
    "code": "XXY",
    "dis": "cont1",
    "note": "Note for cont1"
  },
  {
    "code": "AAW",
    "dis": "cont2",
    "note": "Note for cont2"
  },
  {
    "code": "TTR",
    "dis": "cont5",
    "note": "Note for cont5"
  },
  {
    "code": "MMN",
    "dis": "cont10",
    "note": "Note for cont10"
  }
]

How can I fix this problem?

4 Answers
new_array.forEach(o1 => { // for every replacement object
  // find the corresponding object in the original array
  const found = arr1.find(o2 => o2.code === o1.code); 
  // if there is a corresponding object
  if (found) {
    // copy its properties over
    found.dis = o1.dis;
    found.note = o1.note;
  }
})

Note this has a poor O(n^2) time complexity, consider using a set for faster lookups as recommended by other answers if you have a large dataset.

Given a method which can merge an item from the original, with an array of possible updates:

const mergeItem = (item, arr, finder) =>{
  var other = arr.find(x => finder(item,x));
  if(other != null){
    Object.entries(other).forEach(([key,value]) => item[key] = value);
  }
  return item;
}

The code to merge the 2 arrays is fairly straightforward

var result = arr1.map(item => mergeItem(item,new_array, (x,y) => x.code == y.code));

Live example:

const arr1 = [{"code":"XXY","dis":"cont1","note":"Note for cont1"},{"code":"AAW","dis":"cont2","note":"Note for cont2"},{"code":"TTR","dis":"cont5","note":"Note for cont5"},{"code":"MMN","dis":"cont10","note":"Note for cont10"}];
const new_array = [{"code":"AAW","dis":"cont2 new","note":"Note for cont2"},{"code":"TTR","dis":"cont5","note":"New Note for cont5"}];
  
  
const mergeItem = (item, arr, finder) =>{
  var other = arr.find(x => finder(item,x));
  if(other != null){
    Object.entries(other).forEach(([key,value]) => item[key] = value);
  }
  return item;
}

var result = arr1.map(item => mergeItem(item,new_array, (x,y) => x.code == y.code));

console.log(result);

const mappedArray = arr1.map((x) => {
  const filteredValue = new_array.filter((y) => y.code === x.code);
  return filteredValue.length > 0 ? filteredValue[0] : x;
});

Create an object with second array where code is a key to find element in O(1) time So, complexity reduce to O(n) time.

const arr1 = [{
    code: "XXY",
    dis: "cont1",
    note: "Note for cont1"
  },
  {
    code: "AAW",
    dis: "cont2",
    note: "Note for cont2"
  },
  {
    code: "TTR",
    dis: "cont5",
    note: "Note for cont5"
  },
  {
    code: "MMN",
    dis: "cont10",
    note: "Note for cont10"
  }
]

const new_array = [{
    "code": "AAW",
    "dis": "cont2 new",
    "note": "Note for cont2"
  },
  {
    "code": "TTR",
    "dis": "cont5",
    "note": "New Note for cont5"
  }
]

const t = new_array.reduce((res, item) => {
  res[item.code] = item
  return res;
}, {})

arr1.forEach(item => {
  const found = t[item.code]
  if (found) {
    item.dis = found.dis
    item.note = found.note
  }
})
console.log(arr1)

Related