TransWikia.com

¿Cómo relacionar elementos de un Array entre ellos?

Stack Overflow en español Asked by Nicolas Oñate on August 26, 2021

Dispongo de un código para contabilizar unos elementos recibidos en json, para pintarlos en un gráfico, tengo tres tipos de elementos:

  1. Padre
  2. Hijo
  3. Nieto

La lógica que he usado es que a medida que vayan apareciendo se van contabilizando, pero al aparecer un nieto con dos hijos me ha descuadrado completamente.

  • El padre es único, solo sale una vez.
  • Los hijos pueden ser n, pero todos apuntan al padre.
  • Los nietos pueden apuntar a varios hijos.

Este ultimo punto es el que me ha descuadrado completamente, ya que si dispongo de:

[
    //ELEMENTO PADRE
    {Id: "234L", Padre: "", Nombre: "Padre"},
    //ELEMENTOS HIJOS
    {Id: "247P", Padre: "234L", Nombre: "Hijo1"},
    {Id: "248P", Padre: "234L", Nombre: "Hijo2"},
    //ELEMENTOS NIETOS
    {Id: "50132", Padre: "247P", Nombre: "Nieto1"},
    {Id: "50674", Padre: "247P", Nombre: "Nieto2"},
    {Id: "49964", Padre: "248P", Nombre: "Nieto3"},
    //Elemento nieto con dos hijos
    {Id: "50132", Padre: "248P", Nombre: "Nieto1"}
]

Me contabiliza el ultimo hijo mal con la siguiente lógica:

var json = [{Id: "234L", Padre: "", Nombre: "Padre"},
            {Id: "247P", Padre: "234L", Nombre: "Hijo1"},
            {Id: "248P", Padre: "234L", Nombre: "Hijo2"},
            {Id: "50132", Padre: "247P", Nombre: "Nieto1"},
            {Id: "50674", Padre: "247P", Nombre: "Nieto2"},
            {Id: "49964", Padre: "248P", Nombre: "Nieto3"},
            {Id: "50132", Padre: "248P", Nombre: "Nieto1"}];
            
let count = {};

var obj = json.filter(elem => {
  if (count[elem.Id] === undefined) {
    if (elem.Id.includes("P")) {
      count[elem.Id] = 1;
      count[elem.Padre]++;
    } else if (elem.Id.includes("L")) {
      count[elem.Id] = 0;
    } else {
      count[elem.Id] = 1;
    }
    return true;
  } else {
    count[elem.Padre]++;
    count[elem.Id]++;
    return false;
  }
});

obj.forEach(elem => elem.Repetido = count[elem.Id]);

console.log("obj", obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Esto me da de resultado:

"obj", [{
  Id: "234L",
  Nombre: "Padre",
  Padre: "",
  Repetido: 2 //BIEN
}, {
  Id: "247P",
  Nombre: "Hijo1",
  Padre: "234L",
  Repetido: 1 //MAL
}, {
  Id: "248P",
  Nombre: "Hijo2",
  Padre: "234L",
  Repetido: 2 //MAL
}, {
  Id: "50132",
  Nombre: "Nieto1",
  Padre: "247P",
  Repetido: 2 //MAL 
}, {
  Id: "50674",
  Nombre: "Nieto2",
  Padre: "247P",
  Repetido: 1 //BIEN
}, {
  Id: "49964",
  Nombre: "Nieto3",
  Padre: "248P",
  Repetido: 1 //BIEN
}]

Para que sea correcto Nieto1 debería contabilizarse en dos sitios el primero en Hijo1 y el segundo en Hijo2 ya que está repetido pero cada uno apunta a diferentes padres, así que debería quedar así:

"obj", [{
  Id: "234L",
  Nombre: "Padre",
  Padre: "",
  Repetido: 2
}, {
  Id: "247P",
  Nombre: "Hijo1",
  Padre: "234L",
  Repetido: 2
}, {
  Id: "248P",
  Nombre: "Hijo2",
  Padre: "234L",
  Repetido: 2
}, {
  Id: "50132",
  Nombre: "Nieto1",
  Padre: "247P",
  Repetido: 1 //Primer Nieto1 que apunta a Hijo1
}, {
  Id: "50674",
  Nombre: "Nieto2",
  Padre: "247P",
  Repetido: 1
}, {
  Id: "49964",
  Nombre: "Nieto3",
  Padre: "248P",
  Repetido: 1
}, {
  Id: "50132",
  Nombre: "Nieto1",
  Padre: "248P",
  Repetido: 1 //Segundo Nieto1 que apunta a Hijo2
}]

¿Cómo puedo solventarlo?

2 Answers

En general, podrías solucionarlo iterando sobre tu array de usuarios y comprobando si cada uno está presente en el array original.

En este ejemplo se ha usado Array.map() para clonar el array original y, para comprobar el numero de repeticiones usamos Array.filter() aplicando las relaciones padre-hijo-nieto.

const initialCollection = [
    //ELEMENTO PADRE
    {Id: "234L", Padre: "", Nombre: "Padre"},
    //ELEMENTOS HIJOS
    {Id: "247P", Padre: "234L", Nombre: "Hijo1"},
    {Id: "248P", Padre: "234L", Nombre: "Hijo2"},
    //ELEMENTOS NIETOS
    {Id: "50132", Padre: "247P", Nombre: "Nieto1"},
    {Id: "50674", Padre: "247P", Nombre: "Nieto2"},
    {Id: "49964", Padre: "248P", Nombre: "Nieto3"},
    //Elemento nieto con dos hijos
    {Id: "50132", Padre: "248P", Nombre: "Nieto1"}
];

const withChildren = initialCollection.map(el => {
  const childrenCount = initialCollection.filter(item => item.Padre === el.Id).length;
  
  return {...el, Repeticiones: childrenCount || 1};
});

console.log(withChildren)

Correct answer by Fernando Carrascosa on August 26, 2021

No estoy seguro si es lo que buscas pero podrías probar algo así:

let count = {};

json.forEach(elem => {
  if (elem.Padre !== "") {
    count[elem.Padre] = count[elem.Padre] ? count[elem.Padre] + 1 : 1
    count[elem.Id] = 1
  }
});

const obj = json.map(elem => ({ ...elem, repetido: count[elem.Id] || 0 }))

console.log("obj", obj);

El padre quedaría con 0, los hijos con 3 y los nietos con 1.

Answered by germanescobar on August 26, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP