Estoy aprendiendo el script Java y tratando de fusionar una matriz de objetos según las propiedades específicas de ese objeto.
Por ejemplo, tengo la siguiente matriz que contiene objetos de propiedades a,b,c,pet y age. Quiero crear una nueva matriz con mascotas y edades agrupadas si las propiedades a, b, c son las mismas para 2 objetos. Si alguna de las propiedades en a, b, c no coincide, quiero agregarlas como un nuevo objeto a mi matriz de salida.
myArray = [ { a: 'animal', b: 'white', c: true, pet: 'dog1', age: 1 }, { a: 'animal', b: 'white', c: true, pet: 'dog2', age: 2 }, { a: 'animal2', b: 'white', c: true, pet: 'cat1', age: 5 }, { a: 'animal2', b: 'black', c: false, pet: 'cat2', age: 1 } ]Matriz de salida agrupada por propiedades a,b,c. el primer elemento de mi matriz de salida contiene los valores combinados de los objetos 0,1 en la matriz de entrada, ya que tienen las mismas propiedades que a, b, c. los restantes se agregan como valores separados ya que difieren en una de las propiedades.
outputArray = [ { a: 'animal', b: 'white', c: true, pets: [{pet:'dog1,age:1},{pet:dog2,age:2}] }, { a: 'animal2', b: 'white', c: true, pets: [{pet: 'cat1', age:5}] }, { a: 'animal2', b: 'black', c: false, pets:[{pet: 'cat2', age: 1}] } ]Hacia el final, quiero una matriz con todos los elementos agrupados por propiedad a, b, c. ¿Hay una manera eficiente de esto? Probé fuerza bruta con bucles for pero no funcionó.
TIA.
1) Puede lograr fácilmente el resultado usando Map y for..of
const myArray = [ { a: "animal", b: "white", c: true, pet: "dog1", age: 1, }, { a: "animal", b: "white", c: true, pet: "dog2", age: 2, }, { a: "animal2", b: "white", c: true, pet: "cat1", age: 5, }, { a: "animal2", b: "black", c: false, pet: "cat2", age: 1, }, ]; const dict = new Map(); for (let { a, b, c, ...rest } of myArray) { const key = `${a}|${b}|${c}`; !dict.has(key) ? dict.set(key, { a, b, c, pets: [{ ...rest }] }) : dict.get(key).pets.push(rest); } const result = [...dict.values()]; console.log(result); /* This is not a part of answer. It is just to give the output full height. So IGNORE IT */ .as-console-wrapper { max-height: 100% !important; top: 0; 2) También puede lograr el mismo resultado usando Object.values y reduce
const myArray = [ { a: "animal", b: "white", c: true, pet: "dog1", age: 1, }, { a: "animal", b: "white", c: true, pet: "dog2", age: 2, }, { a: "animal2", b: "white", c: true, pet: "cat1", age: 5, }, { a: "animal2", b: "black", c: false, pet: "cat2", age: 1, }, ]; const result = Object.values( myArray.reduce((dict, { a, b, c, ...rest }) => { const key = `${a}|${b}|${c}`; !dict[key] ? (dict[key] = { a, b, c, pets: [{ ...rest }] }) : dict[key].pets.push(rest); return dict; }, {}) ); console.log(result); /* This is not a part of answer. It is just to give the output full height. So IGNORE IT */ .as-console-wrapper { max-height: 100% !important; top: 0;