es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Typescript: Cómo agrupar un objeto de lista nombrada de objetos por el nombre del campo

Tengo que manipular datos en este maravilloso lenguaje que es javascript. Hasta ahí logré lo que necesitaba por mi cuenta, pero llegué a mis límites ahí.

Es bastante difícil explicar cómo está estructurado mi datos, así que hagamos un esquema. Esto es lo que tengo :

    obj: {[key: string]: {name: string, type: string}[]} = 
    {
        "animals": [
          {name: "Louis", type: "dog"},
          {name: "John", type: "cat"},
          {name: "Jordan", type: "dog"},
        ]
        "cars" : [
          {name: "alpha", type: "ferrari"},
          {name: "beta", type: "ferrari"},
          {name: "charlie", type: "mercedes"},
        ]
     }

Lo que intento lograr es agrupar cada objeto en la lista por tipo. Esto se vería así:

obj: {[key: string]: {[key: string]: {name: string, type: string}[]}} = 
{
    "animals": {
      "dog": [
          {name: "Louis", type: "dog"},
          {name: "Jordan", type: "dog"},
      ],
      "cat": [
          {name: "John", type: "cat"},
      ]
    }
    "cars" : {
      "ferrari": [
          {name: "alpha", type: "ferrari"},
          {name: "beta", type: "ferrari"},
      ],
      "mercedes": [
          {name: "charlie", type: "mercedes"},   
      ]
    }
 }

¿Tienes alguna idea de cómo lograr eso?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes lograr esto usando el método reduce() en el objeto obj original. Aquí hay un ejemplo de código para lograr el resultado requerido:

    const obj = {
        "animals": [
            {name: "Louis", type: "perro"},
            {name: "John", type: "gato"},
            {name: "Jordan", type: "perro"},
        ],
        "cars": [
            {name: "alfa", type: "ferrari"},
            {name: "beta", type: "ferrari"},
            {name: "charlie", type: "mercedes"},
        ]
    };
    
    const result = Object.keys(obj).reduce((acc, key) => {
        acc[key] = obj[key].reduce((innerAcc, item) => {
            if (!innerAcc[item.type]) innerAcc[item.type] = [];
            innerAcc[item.type].push(item);
            return innerAcc;
        }, {});
        return acc;
    }, {});
    
    console.log(result);
    

    En este código, se llama al método reduce() en la matriz Object.keys(obj), lo que devuelve un acumulador inicial de un objeto vacío {}. Dentro de la función reductora, key representa cada clave en el objeto obj original (es decir, “animals” y “cars”).

    Luego, obj[key] representa el valor de matriz de cada clave (es decir, la matriz de objetos de animales y la matriz de objetos de automóviles). El método reduce() se vuelve a llamar en esta matriz, con un acumulador inicial de un objeto vacío {}. Dentro de la función reductora interna, item representa cada objeto dentro de la matriz (es decir, cada objeto de animal o automóvil).

    Luego verifica si la propiedad item.type existe en el objeto acumulador actual (innerAcc). Si no existe, se crea una nueva matriz para ese tipo. El objeto item se agrega luego a esa matriz.

    Finalmente, se devuelve el innerAcc, que se convierte en el siguiente valor acumulador para la próxima iteración del método reduce().

    El objeto resultante se asigna a la propiedad acc[key], que es el valor acumulador para la función reduce() externa.

    El resultado final debería ser la estructura de objeto deseada.

Comments are closed.