¿Alguien sabe de una manera (lodash si es posible también) de agrupar una matriz de objetos por una clave de objeto y luego crear una nueva matriz de objetos basada en la agrupación? Por ejemplo, tengo una variedad de objetos de automóviles:
var cars = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];
Quiero hacer una nueva matriz de objetos de automóviles que se agrupen por make
:
var cars = {
'audi': [
{
'model': 'r8',
'year': '2012'
}, {
'model': 'rs5',
'year': '2013'
},
],
'ford': [
{
'model': 'mustang',
'year': '2012'
}, {
'model': 'fusion',
'year': '2015'
}
],
'kia': [
{
'model': 'optima',
'year': '2012'
}
]
}
groupBy
?Respuestas:
La respuesta de Timo es cómo lo haría. Simple
_.groupBy
, y permite algunas duplicaciones en los objetos en la estructura agrupada.Sin embargo, el OP también solicitó
make
que se eliminen las claves duplicadas . Si quisieras ir hasta el final:Rendimientos:
Si desea hacer esto usando Underscore.js, tenga en cuenta que
_.mapValues
se llama a su versión de_.mapObject
.fuente
En Javascript simple, puedes usarlo
Array#reduce
con un objetofuente
result
resultados?Object.entries
y recorrer los pares clave / valor.make
conjunto de datos una vez agrupado? Está tomando espacio extra.Que busca
_.groupBy()
.Eliminar la propiedad por la que está agrupando los objetos debería ser trivial si es necesario:
Como beneficio adicional, obtienes una sintaxis aún mejor con las funciones de flecha ES6:
fuente
var grouped = _.groupBy(cars, 'make');
no necesita ninguna función, si el descriptor de acceso es un nombre de propiedad simple.La versión corta para agrupar una matriz de objetos por una determinada clave en es6:
La versión más larga:
Parece que la pregunta original pregunta cómo agrupar los automóviles por marca, pero omita la marca en cada grupo. Entonces la respuesta se vería así:
fuente
Aquí está su propia
groupBy
función, que es una generalización del código de: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscorefuente
fuente
Me iría
REAL GROUP BY
para JS Arrays ejemplo exactamente la misma tarea aquífuente
Puede intentar modificar el objeto dentro de la función llamada por iteración por _.groupBy func. ¡Observe que la matriz fuente cambia sus elementos!
fuente
make
propiedad, y también es más legible.También es posible con un
for
bucle simple :fuente
for ( let { TABLE_NAME, ...fields } of source) { result[TABLE_NAME] = result[TABLE_NAME] || []; result[TABLE_NAME].push({ ...fields }); }
Para casos en los que la clave puede ser nula y queremos agruparlos como otros
fuente
Cree un método que pueda reutilizarse
A continuación, puede agrupar por cualquier criterio
fuente
Versión prototipo usando ES6 también. Básicamente, esto usa la función de reducción para pasar un acumulador y un elemento actual, que luego usa esto para construir sus matrices "agrupadas" en función de la clave pasada. la parte interna de la reducción puede parecer complicada, pero esencialmente se está probando para ver si la clave del objeto pasado existe y, si no es así, crear una matriz vacía y agregar el elemento actual a esa matriz recién creada, de lo contrario, usar la propagación El operador pasa todos los objetos de la matriz de claves actual y agrega el elemento actual. ¡Espero que esto ayude a alguien!.
fuente
También puede utilizar un
array#forEach()
método como este:fuente
fuente
Solo prueba este, me funciona bien.
let grouped = _.groupBy(cars, 'make');
fuente
Hice un punto de referencia para probar el rendimiento de cada solución que no usa bibliotecas externas.
JSBen.ch
La
reduce()
opción, publicada por @Nina Scholz parece ser la óptima.fuente
Me gustó la respuesta @metakunfu, pero no proporciona exactamente la salida esperada. Aquí hay una actualización que elimina "make" en la carga útil final de JSON.
Salida:
fuente
Con lodash / fp puede crear una función con
_.flow()
ese primer grupo mediante una tecla, y luego asignar cada grupo y omitir una tecla de cada elemento:fuente
Sobre la base de la respuesta de @Jonas_Wilms si no desea escribir en todos sus campos:
No hice ningún punto de referencia, pero creo que usar un bucle for también sería más eficiente que cualquier cosa sugerida en esta respuesta .
fuente
fuente
Matriz agrupada de objetos en mecanografiado con esto:
fuente
Me encanta escribirlo sin dependencia / complejidad, simplemente js simple.
fuente
Aquí hay otra solución para ello. De acuerdo a lo pedido.
Salida:
fuente
Aquí hay una solución inspirada en Collectors.groupingBy () en Java:
Esto le dará un objeto Map.
fuente