FNSP Web Page

Agrupar listas com Object.groupBy

O Object.groupBy entrou no JavaScript com o ECMAScript 2024 e resolve uma coisa que toda a gente já escreveu à mão pelo menos uma vez: separar uma lista em grupos, segundo um critério qualquer.

O que muda

  • Deixa de ser preciso um reduce com um acumulador e a verificação do costume para o caso de a chave ainda não existir.

  • O objeto devolvido não tem protótipo — não herda toString nem nada — portanto uma chave chamada constructor não estraga nada.

  • As chaves são sempre texto. Quem precisar de agrupar por objetos ou por números a sério tem o Map.groupBy, que devolve um Map.

1. O antes e o depois

const despesas = [
  { descricao: 'Alojamento', valor: 120, categoria: 'viagem' },
  { descricao: 'Almoço', valor: 14, categoria: 'comida' },
  { descricao: 'Comboio', valor: 32, categoria: 'viagem' },
  { descricao: 'Café', valor: 2, categoria: 'comida' },
];

// Antes: acumulador, verificação, e a chave criada à mão
const antes = despesas.reduce((grupos, despesa) => {
  grupos[despesa.categoria] ??= [];
  grupos[despesa.categoria].push(despesa);
  return grupos;
}, {});

// Depois
const porCategoria = Object.groupBy(despesas, (despesa) => despesa.categoria);

console.log(porCategoria.viagem.length); // 2

2. Agrupar por um critério calculado

A função recebe também o índice, e o que ela devolver é a chave. Não tem de ser um campo do objeto:

const porPreco = Object.groupBy(despesas, (despesa) =>
  despesa.valor > 30 ? 'caras' : 'baratas'
);

console.log(Object.keys(porPreco)); // [ 'caras', 'baratas' ]

3. Quando a chave não é texto

const lisboa = { nome: 'Lisboa' };
const funchal = { nome: 'Funchal' };

const registos = [
  { destino: lisboa, dias: 3 },
  { destino: funchal, dias: 10 },
  { destino: lisboa, dias: 1 },
];

// Com Object.groupBy, ambos os destinos viravam a chave "[object Object]"
const porDestino = Map.groupBy(registos, (registo) => registo.destino);

console.log(porDestino.get(lisboa).length); // 2

Está nos browsers desde 2024 e no Node a partir da versão 21. Em código que tenha de correr em sítios mais antigos, o reduce de sempre continua a servir.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.