Tengo estas dos matrices:
const goodCars = [ { name: 'ferrari', price: 22000, condition: { isGood: true, isBad: false } }, { name: 'ford', price: 21000, condition: { isGood: true, isBad: false } }, { name: 'bmw', price: 20000, condition: { isGood: true, isBad: false } }, ]; const badCars = [ { name: 'ford', price: 1111, condition: { isGood: false, isBad: true } }, { name: 'honda', price: 8000, condition: { isGood: false, isBad: true } }, ];Mi objetivo es producir esta matriz final:
const finalCarList = [ { name: 'ferrari', price: 22000, condition: { isGood: true, isBad: false } }, { name: 'ford', price: 21000, condition: { isGood: true, isBad: false }, toCompareWith: { name: 'ford', price: 1111, condition: { isGood: false, isBad: true } }, }, { name: 'bmw', price: 20000, condition: { isGood: true, isBad: false } }, { name: 'honda', price: 8000, condition: { isGood: false, isBad: true } }, ]; Básicamente, quiero fusionar las dos matrices goodCars y badCars en una sola, pero si los autos existen tanto en las matrices buenas como en las malas, entonces quiero agregar el auto malo a la matriz de autos buenos como un nuevo campo toCompareWith: {...} (visto arriba)
Intenté usar map() , reduce() , for loops, etc. pero mi cerebro se topó con una pared y no me acerco más.
Mi intento:
goodCars.map((gc) => { badCars.map((bc) => { if (isCarMatch(gc, bc)) { finalCarList = [ ...finalCarList, { ...gc, toCompareWith: bc }, ]; } }); });La respuesta que elegí se basó en la correcta marcada a continuación: ✅
let finalCarList: Array<Car> = [...goodCars]; badCars?.forEach((bc) => { const match: Car | undefined = goodCars.find((gc) => isCarMatch(gc, bc)); match ? (match.toCompareWith = bc) // Slot in matching item : (finalCarList = [...finalCarList, bc]); });No debe usar bucles anidados.
Comience copiando goodCars a finalCarList . Luego badCars . Si el auto está en goodCars , agregue el mal auto como la propiedad toCompareWith . De lo contrario, introdúzcalo en finalCarList .
finalCarList = [...goodCars]; badCars.forEach(bc => { match = goodCars.find(gc => isCarMatch(gc, bc)); if (match) { match.toCompareWith = bc; } else { finalCarList.push(bc); } }); Además, en general, no debe usar map() si la función de devolución de llamada no devuelve nada. Si se llama solo por efectos secundarios, use forEach() .
A continuación se muestra un ejemplo que usa dos bucles for...of . El ciclo externo es la primera matriz y el ciclo interno es la segunda matriz que usa .entries() para rastrear un índice de coincidencias. Si hay una coincidencia, el objeto de la segunda matriz se elimina y se asigna como el valor de la propiedad .toCompareWith del objeto coincidente de la primera matriz. Una vez que se completan los bucles, ambas matrices se fusionan.
const goodCars = [ { name: 'ferrari', price: 22000, condition: { isGood: true, isBad: false } }, { name: 'ford', price: 21000, condition: { isGood: true, isBad: false } }, { name: 'bmw', price: 20000, condition: { isGood: true, isBad: false } }, ]; const badCars = [ { name: 'ford', price: 1111, condition: { isGood: false, isBad: true } }, { name: 'honda', price: 8000, condition: { isGood: false, isBad: true } }, ]; const mergeCars = (arrA, arrB) => { for (let carA of arrA) { for (let [idx, carB] of arrB.entries()) { if (carA.name === carB.name && carA.condition.isGood !== carB.condition.isGood) { carA.toCompareWith = carB; arrB.splice(idx, 1); } } } return [...arrA, ...arrB]; }; console.log(mergeCars(goodCars, badCars));