1

I have two arrays like this

 let array1 =   [{
      'id': 1,
      'name': 'A'
    }, {
      'id': 2,
      'name': 'B'
    }, {
      'id': 3,
      'name': 'C'
    }]

let array2 =   [{
      'id': 1,
      'name': 'x'
    }, {
      'id': 2,
      'name': 'y'
    }]

I want to update array 1 with the array 2 object values which are matching based on id values. Result would be something like this.

 [{
      'id': 1,
      'name': 'x'
    }, {
      'id': 2,
      'name': 'y'
    }, {
      'id': 3,
      'name': 'C'
    }]

I have written something like this but not working .

    array1.forEach(item1 => {
        const itemFromArr2 = array2.find(item2 => item2.id== item1.id);
        if (itemFromArr2) {
           item1= itemFromArr2;
        }
     }
  )

Please suggest me how to do this.

4 Answers 4

5

You might want to check this one-liner out:

array1.map(e => (e.name = array2.find(a => a.id == e.id)?.name || e.name, e));

Explanation: We are mapping over array1 and searching for the matching id in array2, if it is found (array2.find(a => a.id == e.id)?.name), we override the name property (e.name = ...), otherwise we keep it as it is (... || e.name).

Small example:

let array1 = [{
  'id': 1,
  'name': 'A'
}, {
  'id': 2,
  'name': 'B'
}, {
  'id': 3,
  'name': 'C'
}]

let array2 = [{
  'id': 1,
  'name': 'x'
}, {
  'id': 2,
  'name': 'y'
}]

const newarray = array1.map(e => (e.name = array2.find(a => a.id == e.id)?.name || e.name, e));
console.log(newarray);

Edit according to @Roster's comment, if you want to override the whole entry use this line:

array1.map(e => (e = array2.find(a => a.id == e.id) || e, e));

Second example:

let array1 = [{
  'id': 1,
  'name': 'A'
}, {
  'id': 2,
  'name': 'B'
}, {
  'id': 3,
  'name': 'C'
}]

let array2 = [{
  'id': 1,
  'name': 'x'
}, {
  'id': 2,
  'name': 'y',
  'otherproperty': 42
}]

const newarray = array1.map(e => (e = array2.find(a => a.id == e.id) || e, e));
console.log(newarray);

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks , But what if i have 4 or 5 fields ? i want to update the object irrespective of properties value check. if id matches then just need to update it with array 2 object
Awesome Explanation and Answer. But again would like to know last parameter , e) ? What it indicates. Sorry I am new to js/ ts
Good code, but I think it can be a little shorter array1.map((e) => array2.find(({ id }) => id===e.id) ?? e )
1

Convert the update array to a Map, then iterate the target array with Array.map(), and merge it with the object of the same key in the upateMap if it exists:

const fn = (predicate, target, update) => {
  const updateMap = new Map(update.map(o => [predicate(o), o]))
  
  return target.map(o => {
    const key = predicate(o)
    
    return updateMap.has(key)
      ? { ...o, ...updateMap.get(key)}
      : o
  })
}

const array1 = [{"id":1,"name":"A"},{"id":2,"name":"B"},{"id":3,"name":"C"}]
const array2 = [{"id":1,"name":"x"},{"id":2,"name":"y"}]

const result = fn(o => o.id, array1, array2);
console.log(result);

With types (TS playground):

const fn = <T>(predicate: (arg: T) => any, target: T[], update: T[]) => {
  const updateMap = new Map(update.map(o => [predicate(o), o]))
  
  return target.map(o => {
    const key = predicate(o)
    
    return updateMap.has(key)
      ? { ...o, ...updateMap.get(key)}
      : o
  })
}

Comments

0

Using a hashmap to update the array.

The reason of hashmap is for performance.

const array1 = [
    { id: 1, name: "A" },
    { id: 2, name: "B" },
    { id: 3, name: "C" },
];

const array2 = [
    { id: 1, name: "x" },
    { id: 2, name: "y" },
];

const hashMap2 = array2.reduce((carry, item) => {
    const { id } = item;
    if (!carry[id]) {
        carry[id] = item;
    }
    return carry;
}, {});

const output = array1.map(item => {
    const newName = hashMap2[item.id]?.name;
    if (newName) {
        item.name = newName;
    }
    return item;
});

console.log(output);

Comments

0

Here's a solution using Generics:

const array1 =   [{
      'id': 1,
      'name': 'A'
    }, {
      'id': 2,
      'name': 'B'
    }, {
      'id': 3,
      'name': 'C'
    }]

const array2 =   [{
      'id': 1,
      'name': 'x'
    }, {
      'id': 2,
      'name': 'y'
    }]


function mergeArray<T>(arr1: T[], arr2: T[], identifier: keyof T): T[] {
    for(const oItem of arr2){
        const itemInArr1 = 
            arr1.find(item => item[identifier] === oItem[identifier]);
        if(itemInArr1){
            for(const key in itemInArr1){
                itemInArr1[key] = oItem[key];
            }
        } else {
            arr1.push(oItem);
        }
    }
    return arr1;
}

console.log(mergeArray(array1,array2, 'id'));

Playground

This iterates over the itmes in array2and checks their existence inside array1 based on the identifier.

Based on whether or not the item exists in array1, the item will be modified, or the item from array2 is pushed into array1.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.