He estado buscando durante un tiempo en este hilo , pero todo lo que pude encontrar allí como resultado de la comparación entre dos matrices es qué elementos se agregaron o eliminaron.
Lo que necesito es adivinar qué elemento se ha movido de un índice a otro.
Ejemplo: tomemos la siguiente matriz:
let array1 = ['A', 'B', 'C', 'D', 'E', 'F'];El elemento 'E' se moverá del 4º índice al 2º índice y obtendremos:
let array2 = ['A', 'B', 'E', 'C', 'D', 'F'];Necesito una función que devuelva qué elemento ha cambiado, su nuevo índice en el nuevo arreglo2 y su índice anterior en el arreglo1;
Hice algo como algo en el pasado que, aproximadamente (por lo que recuerdo ahora) consiste en buscar el primer elemento diferente entre ambas matrices y luego verificar la secuencia detrás de él para adivinar si el elemento diff encontrado es en sí mismo el movido o el que ocupó su lugar.
Entonces, antes de volver a escribirlo, desearía poder encontrar uno listo para usar;)
El enfoque es el siguiente...
-1 debido a un valor/elemento eliminado), cree un objeto similar al estado con datos del valor y los índices e introdúzcalo en la matriz de resultados. La implementación se basa en Array.prototype.reduce donde procesaría la matriz de elementos actual y pasaría la matriz de elementos recientes como parte de un acumulador/recolector como el valor inicial de la función reductora.
function collectPositionChange({ recent, result }, value, currentIdx) { const recentIdx = recent.indexOf(value); if (recentIdx !== currentIdx) { result.push({ value, currentIdx, recentIdx }); } return { recent, result }; } const recentItems = ['A', 'B', 'E', 'C', 'D', 'F']; const currentItems = ['A', 'B', 'C', 'D', 'E', 'F']; console.log( currentItems .reduce(collectPositionChange, { recent: recentItems, result: [] }) .result ); console.log( ['A', 'C', 'D', 'B', 'E', 'F'] .reduce(collectPositionChange, { recent: ['A', 'B', 'C', 'D', 'E', 'F'], result: [] }) .result ); console.log( ['A', 'B', 'C', 'D', 'E', 'F'] .reduce(collectPositionChange, { recent: ['A', 'C', 'D', 'B', 'E', 'F'], result: [] }) .result ); .as-console-wrapper { min-height: 100%!important; top: 0; }No estoy seguro de cuáles son los requisitos completos, pero esto detectará el movimiento hacia adelante y hacia atrás, así como los intercambios de caracteres. Funcionará en cualquier orden, pero su predicción sobre lo que cambió se vuelve menos precisa cuantos más cambios ocurren en una fila. Aquí hay una muestra que usa un diccionario:
const array1 = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']; const array2 = ['A', 'B', 'E', 'C', 'D', 'F', 'H', 'I', 'G', 'K' , 'J']; let globalOffset = 0; let currentSuspect = ""; var dict = new Object(); array1.forEach((char, index) => { dict[char] = index; }); array2.forEach((char, index) => { dict[char] = dict[char] - index; }); let offset = 0; let prevValue = 0; Object.entries(dict).forEach((entry, index) => { const [key, value] = entry; switch(true){ case offset === 0 && value < -1: console.log(`The character ${key} had its index moved forward by ${Math.abs(value)}! \n New index: ${index + Math.abs(value)} - Old index: ${index}`); break; case offset < 0 && value > 1: console.log(`The character ${key} had its index moved backwards by ${value}! \n New index: ${index + offset} - Old index: ${index}`); break; case prevValue === -1 && offset === -1 && value === 1: console.log(`The characters ${key} and ${array2[index]} were swapped!`); break; } prevValue = value; offset += value; }); let array1 = ['A', 'B', 'C', 'D', 'E', 'F']; // test 1 : moving 'B' from index 1 to index 3 let array2 = ['A', 'C', 'D', 'B', 'E', 'F']; // test 2: moving 'E' from 4 to 1 // let array2 = ['A', 'E', 'B', 'C', 'D', 'F']; // test 3 : moving 'A' from 0 to 5 // let array2 = ['B', 'C', 'D', 'E', 'F', 'A']; function getMovedElementInfos(array1, array2) { let firstDiffElIndexInNewArray = array2.findIndex((el, elindx) => el !== array1[elindx]); let firstDiffElInNewArray = array2[firstDiffElIndexInNewArray]; let nextElInNewArray = array2[firstDiffElIndexInNewArray + 1]; let firstDiffElIndexInOldArray = array1.findIndex(el => el === firstDiffElInNewArray); let nextElInOldArray = array1[firstDiffElIndexInOldArray + 1]; let movedEl, movedElFrom, movedElTo; if (nextElInNewArray === nextElInOldArray) { movedEl = array1[firstDiffElIndexInNewArray]; movedElFrom = firstDiffElIndexInNewArray; movedElTo = array2.findIndex(el => el === movedEl); } else { movedEl = firstDiffElInNewArray; movedElFrom = firstDiffElIndexInOldArray; movedElTo = firstDiffElIndexInNewArray; } return { movedEl, movedElFrom, movedElTo } } const { movedEl, movedElFrom, movedElTo } = getMovedElementInfos(array1, array2) console.log('movedEl is: ', movedEl); console.log('movedEl index in old array is: ', movedElFrom); console.log('movedEl index in new array is: ', movedElTo); console.log('array1[movedElFrom]: ', array1[movedElFrom]); console.log('array2[movedElTo]: ', array2[movedElTo]);