El objetivo es crear una nueva matriz anidada basada en 2 matrices planas con objetos. Si una identificación de la lista B coincide con una refId en la lista A, el objeto se agrega como un elemento secundario al objeto de la lista A. Esto crea una nueva matriz de 2 niveles de profundidad, como se muestra en el ejemplo.
Sin embargo, en la Lista B, hay objetos que tienen ID que coinciden con los RefId de sus objetos hermanos. Si ese es el caso, el código debe encontrar coincidencias y luego agregarlas como elementos secundarios de los elementos secundarios del objeto principal. Así, 3 niveles de profundidad. El código debe continuar anidándose hasta que no haya coincidencias posibles.
¿Cómo se puede modificar el siguiente código para anidar cualquier número de niveles de ID y refId coincidentes basados en profundidad?
// TOP LEVEL const listA = [ { "id": 23, "refId": 23, "name": 'list A #1', "isNested": false, "depth": 1, "children": [] }, { "id": 25, "refId": 25, "name": 'list A #1', "isNested": false, "depth": 1, "children": [] } ] // NO HEIRARCHY const listB = [ { "id": 23, "refId": 1234, "name": "test 1", "isNested": true, "depth": 2, "children": [] }, { "id": 25, "refId": 1212, "name": "test 1", "isNested": true, "depth": 2, "children": [] }, { "id": 1234, "refId": 4324, "depth": 3, "name": "test 2", "isNested": true, "children": [] }, { "id": 1234, "refId": 5678, "depth": 3, "name": "test 3", "isNested": true, "children": [] } ] const nestedArr = listA.map( ({ id, name, refId, children }) => { return { id, name, refId, children: listB.filter((b) => { return b.id == refId ? b : '' }), } } ) console.log(nestedArr)Si sus árbitros están en orden, puede hacer lo siguiente:
Map para que pueda acceder a ella fácilmente más tardeid === refId , empújelo como una referencia de nivel superiorchildren const refs = new Map(); const nestedArr = []; for (const ref of listA.concat(listB)) { refs.set(ref.refId, ref); if (ref.id !== ref.refId) { refs.get(ref.id).children.push(ref); } else { nestedArr.push(ref); } } console.log(nestedArr)Aquí hay un fragmento ejecutable:
// TOP LEVEL const listA = [ { "id": 23, "refId": 23, "name": 'list A #1', "isNested": false, "depth": 1, "children": [] }, { "id": 25, "refId": 25, "name": 'list A #1', "isNested": false, "depth": 1, "children": [] } ] // NO HEIRARCHY const listB = [ { "id": 23, "refId": 1234, "name": "test 1", "isNested": true, "depth": 2, "children": [] }, { "id": 25, "refId": 1212, "name": "test 1", "isNested": true, "depth": 2, "children": [] }, { "id": 1234, "refId": 4324, "depth": 3, "name": "test 2", "isNested": true, "children": [] }, { "id": 1234, "refId": 5678, "depth": 3, "name": "test 3", "isNested": true, "children": [] } ]; const refs = new Map(); const nestedArr = []; for (const ref of listA.concat(listB)) { refs.set(ref.refId, ref); if (ref.id !== ref.refId) { refs.get(ref.id).children.push(ref); } else { nestedArr.push(ref); } } console.log(nestedArr)Nota: esto muta los elementos originales
Puede crear un mapa con clave de todos los refId y relacionarlos con los objetos de nodo correspondientes, utilizando el constructor del Map . Luego itere la segunda lista para hacer los archivos adjuntos.
Esto muta las matrices secundarias existentes children por lo que listA tendrá el resultado:
const listA = [{"id": 23,"refId": 23,"name": 'list A #1',"isNested": false,"depth": 1,"children": []},{"id": 25,"refId": 25,"name": 'list A #1',"isNested": false,"depth": 1,"children": []}]; const listB = [{"id": 23,"refId": 1234,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 25,"refId": 1212,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 1234,"refId": 4324,"depth": 3,"name": "test 2","isNested": true,"children": []},{"id": 1234,"refId": 5678,"depth": 3,"name": "test 3","isNested": true,"children": []}]; const map = new Map(listA.concat(listB).map(node => [node.refId, node])); for (const {id, refId} of listB) map.get(id).children.push(map.get(refId)); console.log(listA); Si no desea mutar la entrada original, asegúrese de crear nuevas matrices children :
const listA = [{"id": 23,"refId": 23,"name": 'list A #1',"isNested": false,"depth": 1,"children": []},{"id": 25,"refId": 25,"name": 'list A #1',"isNested": false,"depth": 1,"children": []}]; const listB = [{"id": 23,"refId": 1234,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 25,"refId": 1212,"name": "test 1","isNested": true,"depth": 2,"children": []},{"id": 1234,"refId": 4324,"depth": 3,"name": "test 2","isNested": true,"children": []},{"id": 1234,"refId": 5678,"depth": 3,"name": "test 3","isNested": true,"children": []}]; const map = new Map(listA.concat(listB).map(node => [node.refId, {...node, children:[]}])); for (const {id, refId} of listB) map.get(id).children.push(map.get(refId)); const nestedListA = listA.map(({id}) => map.get(id)); console.log(nestedListA);