Tengo dos arreglos como este
let array1 = [{ 'id': 1, 'name': 'A' }, { 'id': 2, 'name': 'B' }, { 'id': 3, 'name': 'C' }] let array2 = [{ 'id': 1, 'name': 'x' }, { 'id': 2, 'name': 'y' }]Quiero actualizar la matriz 1 con los valores de objeto de la matriz 2 que coinciden según los valores de identificación. El resultado sería algo como esto.
[{ 'id': 1, 'name': 'x' }, { 'id': 2, 'name': 'y' }, { 'id': 3, 'name': 'C' }]He escrito algo como esto pero no funciona.
array1.forEach(item1 => { const itemFromArr2 = array2.find(item2 => item2.id== item1.id); if (itemFromArr2) { item1= itemFromArr2; } } )Por favor sugiérame cómo hacer esto.
Es posible que desee consultar este one-liner:
array1.map(e => (e.name = array2.find(a => a.id == e.id)?.name || e.name, e)); Explicación : estamos mapeando sobre array1 y buscando la identificación coincidente en array2 , si se encuentra ( array2.find(a => a.id == e.id)?.name ), anulamos la propiedad de nombre ( e.name = ... ), de lo contrario lo mantenemos como está ( ... || e.name ).
Pequeño ejemplo:
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);Edite de acuerdo con el comentario de @Roster, si desea anular toda la entrada, use esta línea:
array1.map(e => (e = array2.find(a => a.id == e.id) || e, e));Segundo ejemplo :
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);Convierta la matriz de update en Map , luego itere la matriz de target con Array.map() y combínela con el objeto de la misma clave en upateMap si existe:
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);Con tipos ( juego de TS ):
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 }) }Aquí hay una solución usando Genéricos:
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')); Esto itera sobre los elementos en array2 y verifica su existencia dentro de array1 en función del identificador.
Según si el elemento existe o no en array1 , el elemento se modificará o el elemento de array2 se insertará en array1 .