Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

134
Vistas
Transform JSON array of similar elements into nested array using JavaScript

Say I have the following JSON array:

[
{
    "name": "x",
    "category": "y",
    "attributes": {
        "name": "a",
        "description": "b"
    }
},
{
    "name": "x",
    "category": "y",
    "attributes": {
        "name": "c",
        "description": "d"
    }
}
]

How can I combine the elements where each property is identical, but add the differing properties to a nested array:

[
{
    "name": "x",
    "category": "y",
    "attributes": [
     {
        "name": "a",
        "description": "b"
     },
     {
        "name": "c",
        "description": "d"
     }
  ]
}
]

To be more specific, any differing elements should be appended to the array— for example if the attribute with name "c" had description "b", I would still want the entire attribute appended to the "attributes" list.

I've been unable to find this problem on StackOverflow through extensive searching. I appreciate your help!

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

I was able to slightly modify my inputs to achieve a solution (I have limited knowledge of JS). The new inputs are:

const myJson = [{
    "name": "x",
    "category": "y",
    "attributes": {
      "name": "a",
      "description": "b"
    }
  },
  {
    "attributes": {
      "name": "c",
      "description": "d"
    }
  },
  {
   "category": "z"
  }
]

Now I can iterate through the items (in order). If an item lacks the "masterKey," (in this case "name"), I will add that key/value to the last item with the masterKey or create a list of values & append.

function mergeObjects_(objects) {
    var result = [];
    const masterKey = 'name';

    for (let i = 0; i < objects.length; i++) {
        let object = objects[i];

        if (object.hasOwnProperty(masterKey)) {
            result.push(object);
        } else {
            for (const [key, value] of Object.entries(object)) {
                if (Array.isArray(result[result.length - 1][key])) {
                    result[result.length - 1][key].push(value);
                } else {
                    var attribute_arr = [result[result.length - 1][key]];
                    attribute_arr.push(value);
                    result[result.length - 1][key] = attribute_arr;
                }
            }
        }
    }
    return result;
}

This collapses the sample to the following and works across multiple items

[
    {
        "name": "x",
        "category": [
            "y",
            "z"
        ],
        "attributes": [
            {
                "name": "a",
                "description": "b"
            },
            {
                "name": "c",
                "description": "d"
            }
        ]
    }
]

Of course, this assumes one of the trailing properties exists in the object with the masterKey. For my purposes, this is OK given how the data is generated. Thank you all for your answers and help!

about 4 years ago · Juan Pablo Isaza Denunciar

0

The most straightforward way is to use the reduce function

const data = [
    {
        name: 'x',
        category: 'y',
        attributes: {
            name: 'a',
            description: 'b',
        },
    },
    {
        name: 'x',
        category: 'y',
        attributes: {
            name: 'c',
            description: 'd',
        },
    },
];

const answer = data.reduce((result, current) => {
    const findIndex = result.findIndex((item) => item.name === current.name);

    // if the name does not exist in the result, append it to the result array
    if (findIndex === -1) {
        return [
            ...result,
            {
                name: current.name,
                category: current.category,
                attributes: [current.attributes],
            },
        ];
    }

    return result.map((value, index) => {
        if (index === findIndex) {
            value.attributes.push(current.attributes);
        }
        return value;
    });
}, []);

console.log(answer);

about 4 years ago · Juan Pablo Isaza Denunciar

0

//It's very simple and best for huge data
 var arr = [
       {
          "name": "x",
          "category": "y",
          "attributes": {
             "name": "a",
             "description": "b"
          }
       },
       {
          "name": "x",
          "category": "y",
          "attributes": {
             "name": "c",
             "description": "d"
          }
       }
    ];
    
    var newArr = [];
    var objKeyValue = {};
    arr.forEach(rec => {
       if (objKeyValue[rec.name + rec.category])
          objKeyValue[rec.name + rec.category].attributes.push(rec.attributes);
       else objKeyValue[rec.name + rec.category] = { name: rec.name, category: rec.category, attributes: [rec.attributes] };
    });
    console.log("Output", Object.values(objKeyValue));
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda