Object.groupBy() e Map.groupBy()

Object.groupBy() e Map.groupBy() agrupam itens de um array por uma chave derivada, de forma nativa, sem precisar de reduce() manual ou bibliotecas utilitárias.

Agrupar itens de um array por alguma característica em comum (categoria, status, tipo) é uma tarefa muito comum, mas que sempre exigiu um reduce() manual ou uma biblioteca como o lodash. Agora o JavaScript tem Object.groupBy() e Map.groupBy() nativos para isso.

O jeito antigo (com reduce)

const produtos = [
    { nome: 'Camiseta', categoria: 'roupas' },
    { nome: 'Tênis', categoria: 'calçados' },
    { nome: 'Boné', categoria: 'roupas' },
];

const agrupados = produtos.reduce((acc, produto) => {
    const chave = produto.categoria;
    acc[chave] = acc[chave] ?? [];
    acc[chave].push(produto);
    return acc;
}, {});

Funciona, mas precisa ser reescrito (ou importado de uma biblioteca) toda vez que esse tipo de agrupamento é necessário.

Como funciona o Object.groupBy()

Object.groupBy() recebe um iterável e uma função que retorna a chave de agrupamento para cada item, devolvendo um objeto simples:

const produtos = [
    { nome: 'Camiseta', categoria: 'roupas' },
    { nome: 'Tênis', categoria: 'calçados' },
    { nome: 'Boné', categoria: 'roupas' },
];

const agrupados = Object.groupBy(produtos, produto => produto.categoria);

console.log(agrupados);
// {
//   roupas: [{ nome: 'Camiseta', ... }, { nome: 'Boné', ... }],
//   calçados: [{ nome: 'Tênis', ... }]
// }

Map.groupBy() para chaves não-string

Quando a chave de agrupamento não é uma string (por exemplo, um objeto ou um número usado como referência), Map.groupBy() é a opção mais indicada, já que um Map aceita qualquer tipo de chave:

const pedidos = [
    { id: 1, cliente: { id: 10, nome: 'Ana' } },
    { id: 2, cliente: { id: 20, nome: 'Bruno' } },
    { id: 3, cliente: { id: 10, nome: 'Ana' } },
];

const porCliente = Map.groupBy(pedidos, pedido => pedido.cliente.id);

console.log(porCliente.get(10)); // pedidos 1 e 3

Agrupando por faixa de valor

const numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const pares_impares = Object.groupBy(numeros, n => n % 2 === 0 ? 'par' : 'ímpar');

console.log(pares_impares);
// { par: [2, 4, 6, 8, 10], ímpar: [1, 3, 5, 7, 9] }

Quando usar

Compatibilidade

O suporte já é bom nos navegadores modernos, mas vale sempre conferir antes de usar em produção, principalmente se o projeto precisar suportar navegadores mais antigos.

caniuse

Conclusão

Object.groupBy() e Map.groupBy() resolvem um caso de uso extremamente comum de forma nativa e legível, reduzindo a necessidade de reduce() manual ou de bibliotecas utilitárias só para agrupar dados.

Tecnologia:
js

Deixe seu Comentário!

Comentário
Nome
Email