Alguém sabe de uma maneira (se possível também) de agrupar uma matriz de objetos por uma chave de objeto e criar uma nova matriz de objetos com base no agrupamento? Por exemplo, eu tenho uma matriz de objetos de carro:
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'
},
];
Quero criar uma nova matriz de objetos de carro agrupados 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
?Respostas:
A resposta de Timo é como eu faria isso. Simples
_.groupBy
e permita algumas duplicações nos objetos na estrutura agrupada.No entanto, o OP também solicitou a
make
remoção das chaves duplicadas . Se você quisesse ir até o fim:Rendimentos:
Se você quiser fazer isso usando Underscore.js, observe que sua versão
_.mapValues
é chamada_.mapObject
.fonte
Em Javascript simples, você pode usar
Array#reduce
com um objetofonte
result
resultados?Object.entries
e percorrer os pares chave / valor.make
conjunto de dados depois de agrupado? Está ocupando espaço extra.Você está procurando
_.groupBy()
.A remoção da propriedade que você está agrupando dos objetos deve ser trivial, se necessário:
Como bônus, você obtém uma sintaxe ainda melhor com as funções de seta do ES6:
fonte
var grouped = _.groupBy(cars, 'make');
há necessidade de uma função, se o acessador for um nome de propriedade simples.A versão curta para agrupar uma matriz de objetos por uma certa chave no es6:
A versão mais longa:
Parece que a pergunta original pergunta como agrupar carros por marca, mas omita a marca em cada grupo. Portanto, a resposta seria assim:
fonte
Aqui está sua própria
groupBy
função, que é uma generalização do código em: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscorefonte
fonte
Gostaria de deixar
REAL GROUP BY
para o exemplo JS Arrays exatamente o mesmo desta tarefa aquifonte
Você pode tentar modificar o objeto dentro da função chamada por iteração por _.groupBy func. Observe que a matriz de origem altera seus elementos!
fonte
make
propriedade, e é mais legível também.Também é possível com um
for
loop simples :fonte
for ( let { TABLE_NAME, ...fields } of source) { result[TABLE_NAME] = result[TABLE_NAME] || []; result[TABLE_NAME].push({ ...fields }); }
Nos casos em que a chave pode ser nula e queremos agrupá-los como outros
fonte
Crie um método que possa ser reutilizado
Abaixo, você pode agrupar por qualquer critério
fonte
Versão do protótipo usando o ES6 também. Basicamente, isso usa a função de redução para passar um acumulador e um item atual, que depois usa isso para criar suas matrizes "agrupadas" com base na chave passada. a parte interna da redução pode parecer complicada, mas essencialmente ele está testando para ver se a chave do objeto passado existe e se não criar uma matriz vazia e anexar o item atual à nova matriz criada usando a propagação O operador passa todos os objetos da matriz de chaves atual e acrescenta o item atual. Espero que isso ajude alguém!
fonte
Você também pode usar um
array#forEach()
método como este:fonte
fonte
Apenas tente este que funciona bem para mim.
let grouped = _.groupBy(cars, 'make');
fonte
Fiz uma referência para testar o desempenho de cada solução que não usa bibliotecas externas.
JSBen.ch
A
reduce()
opção, postada por @Nina Scholz, parece ser a melhor.fonte
Eu gostei da resposta @metakunfu, mas ela não fornece exatamente a saída esperada. Aqui está uma atualização que se livra de "make" na carga final JSON.
Resultado:
fonte
Com o lodash / fp, você pode criar uma função com
_.flow()
esse primeiro grupo por uma tecla, mapear cada grupo e omitir uma tecla de cada item:fonte
Com base na resposta de @Jonas_Wilms, se você não quiser digitar todos os seus campos:
Não fiz nenhum benchmark, mas acredito que usar um loop for seria mais eficiente do que qualquer coisa sugerida nesta resposta também.
fonte
fonte
Matriz de objeto agrupada em texto datilografado com isso:
fonte
Adoro escrever sem dependência / complexidade, apenas com js simples e puros.
fonte
Aqui está outra solução para isso. Como pedido.
Resultado:
fonte
Aqui está uma solução inspirada em Collectors.groupingBy () em Java:
Isso dará um objeto de mapa.
fonte