Sé que esto suena divertido ya que codifiqué la solución yo mismo, pero tengo problemas para entender por qué funciona después de no verlo durante un tiempo. El algoritmo resuelve la pregunta de "Actualización de inventario" de freecodecamp, aunque con una prueba fallida (compare y actualice el inventario almacenado en una matriz 2D con una segunda matriz 2D de una nueva entrega. Actualice las cantidades de artículos de inventario existentes actuales (en arr1). Si no se puede encontrar un artículo, agregue el nuevo artículo y la cantidad en la matriz de inventario. La matriz de inventario devuelta debe estar en orden alfabético por artículo). El algoritmo es el siguiente:
function updateInventory(arr1, arr2) { let newInv = [...arr1, ...arr2] //create single list of items only from both arrays let temp = newInv.flat().filter(item => typeof item === 'string') //create list of the index of all duplicate items let duplicates = temp.reduce((acc, item, index) => { if (temp.indexOf(item) != index){ acc.push(index) } return acc }, []) //remove duplicate items for (let index in duplicates) { newInv.splice(index, 1) } //sort by alphabetical order newInv.sort((a,b) => { return a[1] > b[1] ? 1 : -1 }) return newInv } // Example inventory lists var curInv = [ [21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"] ]; var newInv = [ [2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"] ]; updateInventory(curInv, newInv);Según tengo entendido, el resultado esperado debería ser:
[ [ 21, 'Bowling Ball' ], [ 2, 'Dirty Sock' ], [ 1, 'Hair Pin' ], [ 3, 'Half-Eaten Apple' ], [ 5, 'Microphone' ], [ 7, 'Toothpaste' ] ]Sin embargo, lo que se obtiene es:
[ [ 67, 'Bowling Ball' ], [ 2, 'Dirty Sock' ], [ 2, 'Hair Pin' ], [ 3, 'Half-Eaten Apple' ], [ 5, 'Microphone' ], [ 7, 'Toothpaste' ] ]que son los pares duplicados de los elementos que debía eliminar. Estoy seguro de que me estoy perdiendo algo simple, pero simplemente no lo entiendo.
tu ayuda es muy apreciada
Hay dos problemas. El primero es con el bucle for
let duplicates = [4, 6] for (let index in duplicates) { newInv.splice(index, 1) }Estás haciendo un para en no un para de
en bucles sobre los índices ( en como en el índice ..! :)) , para sobre los valores
Si registra el índice en el ciclo, verá 0,1 = los índices de los elementos en duplicados
Cámbielo a para que sea 4,6 = los valores de los elementos en duplicados = los índices de los elementos que desea eliminar. Una alternativa sería
duplicates.forEach(i => newInv.splice(i, 1))El segundo problema es que cuando eliminó el primer elemento, el índice del segundo elemento cambia :-) Por lo tanto, ya no es el índice 6, sino ahora el 5. Esto se puede resolver invirtiendo los duplicados antes del bucle y empalme, así que comience con el índice más alto primero y eliminando 'desde el final hasta el principio'.
Así que esto debería dar el resultado solicitado
function updateInventory(arr1, arr2) { let newInv = [...arr1, ...arr2] //create single list of items only from both arrays let temp = newInv.flat().filter(item => typeof item === 'string') //create list of the index of all duplicate items let duplicates = temp.reduce((acc, item, index) => { if (temp.indexOf(item) != index) { acc.push(index) } return acc }, []).reverse() //remove duplicate items for (let index of duplicates) { newInv.splice(index, 1) } //sort by alphabetical order newInv.sort((a, b) => { return a[1] > b[1] ? 1 : -1 }) return newInv } // Example inventory lists var curInv = [ [21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"] ]; var newInv = [ [2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"] ]; let result = updateInventory(curInv, newInv); console.log(result);Y este sería mi enfoque para resolver la tarea.
function updateInventory(curInv, newInv) { newInv.forEach(newItem => { let newItemName = newItem[1] let inCurrent = curInv.find(currItem => currItem[1] === newItemName) if(!inCurrent) curInv.push(newItem) }) return curInv.sort((a,b) => a[1].localeCompare(b[1])) } // Example inventory lists var curInv = [ [21, "Bowling Ball"], [2, "Dirty Sock"], [1, "Hair Pin"], [5, "Microphone"] ]; var newInv = [ [2, "Hair Pin"], [3, "Half-Eaten Apple"], [67, "Bowling Ball"], [7, "Toothpaste"] ]; let result = updateInventory(curInv, newInv); console.log(result);