Artigo original: JavaScript Array of Objects Tutorial – How to Create, Update, and Loop Through Objects Using JS Array Methods

Em média, eu trabalho com dados de JSON 18 vezes em uma semana. Mesmo assim, ainda preciso pesquisar no Google maneiras específicas de manipulá-los quase sempre. E se houvesse um guia definitivo que pudesse sempre oferecer a você a resposta?

Neste artigo, mostrarei a vocês o básico de como trabalhar com arrays de objetos no JavaScript.

Se você já trabalhou com uma estrutura de JSON, já trabalhou com objetos em JavaScript. Literalmente. Afinal, JSON significa "notação de objetos em JavaScript".

Criar um objeto é simples. Observe:

{
  "color": "purple",
  "type": "minivan",
  "registration": new Date('2012-02-03'),
  "capacity": 7
}

Este objeto representa um carro. Há muitos tipos e cores de carros. Cada objeto, então, representa um carro específico.

purple

Bem, na maioria das vezes, você obtém esses dados de um serviço externo. Algumas vezes, no entanto, você precisa criar objetos e arrays de objetos manualmente. Foi o que fiz ao criar essa loja virtual:

categories

Considerando que cada item da lista de categorias tem essa aparência no HTML:

code

Eu não queria ter de repetir o código acima 12 vezes. Não seria possível fazer a manutenção disso.

Criando um array de objetos

Voltemos aos carros. Vamos ver esse conjunto de carros abaixo:

cars

Podemos representar esses carros como um array da seguinte forma:

let cars = [
  {
    "color": "purple",
    "type": "minivan",
    "registration": new Date('2017-01-03'),
    "capacity": 7
  },
  {
    "color": "red",
    "type": "station wagon",
    "registration": new Date('2018-03-03'),
    "capacity": 5
  },
  {
    ...
  },
  ...
]

Arrays de objetos não permanecem iguais o tempo todo. Quase sempre precisamos manipulá-los. Vamos ver, então, como podemos adicionar objetos a um array já existente.

Adicionando um novo objeto ao início - Array.unshift

beginning

Para adicionar um objeto à primeira posição, usamos Array.unshift.

let car = {
  "color": "red",
  "type": "cabrio",
  "registration": new Date('2016-05-02'),
  "capacity": 2
}
cars.unshift(car);

Adicionando um novo objeto ao final - Array.push

ending

Para adicionar um objeto à última posição, usamos Array.push.

let car = {
 "color": "red",
 "type": "cabrio",
 "registration": new Date('2016-05-02'),
 "capacity": 2
}
cars.push(car);

Adicionando um novo objeto no meio - Array.splice

middle

Para adicionar um objeto no meio, usamos Array.splice. Essa função é muito útil, pois também pode remover itens. Observe seus parâmetros:

Array.splice(
  {índice onde iniciar},
  {quantos itens remover},
  {itens a serem adicionados}
);

Assim, se quisermos adicionar o Volkswagen conversível (cabrio) vermelho na quinta posição, usamos:

let car = {
  "color": "red",
  "type": "cabrio",
  "registration": new Date('2016-05-02'),
  "capacity": 2
}
cars.splice(4, 0, car);

Percorrendo o array de objetos com laços

Aqui, cabe uma pergunta: para quê percorrer um array de objetos com laços? O motivo de eu perguntar isso está no fato de que quase nunca o motivo inicial é aquilo que queremos obter.

O JavaScript fornece muitas funções que podem resolver seu problema sem implementar de fato a lógica em um ciclo geral. Vamos ver isso agora.

Encontrando um objeto em um array a partir de seus valores - Array.find

Suponha que queremos encontrar um carro vermelho. Podemos usar a função Array.find.

cars-colorred
let car = cars.find(car => car.color === "red");

Essa função retorna o primeiro elemento correspondente:

console.log(car);
// resultado:
// {
//   color: 'red',
//   type: 'station wagon',
//   registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
//   capacity: 5
// }

Também é possível procurar por diversos valores:

let car = cars.find(car => car.color === "red" && car.type === "cabrio");

Neste caso, acharemos o último carro da lista.

Obtendo diversos itens de um array que atendam a uma condição - Array.filter

A função Array.find retorna apenas um objeto. Se quisermos obter todos os carros vermelhos, precisamos usar Array.filter.

cars-colorred2
let redCars = cars.filter(car => car.color === "red");
console.log(redCars);
// resultado:
// [
//   {
//     color: 'red',
//     type: 'station wagon',
//     registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 5
//   },
//   {
//     color: 'red',
//     type: 'cabrio',
//     registration: 'Sat Mar 03 2012 01:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 2
//   }
// ]

Transformando objetos de um array - Array.map

Isso é algo de que precisamos com frequência, transformar um array de objetos em um array de objetos diferentes. Esse é um trabalho para o Array.map. Digamos que nossa intenção é classificar nossos carros em três grupos, com base em seu tamanho.

cars-sizes
let sizes = cars.map(car => {
  if (car.capacity <= 3){
    return "small";
  }
  if (car.capacity <= 5){
    return "medium";
  }
  return "large";
});
console.log(sizes);
// resultado:
// ['large','medium','medium', ..., 'small']

Também é possível criar um novo objeto se precisarmos de mais valores:

let carsProperties = cars.map(car => {
 let properties = {
   "capacity": car.capacity,
   "size": "large"
 };
 if (car.capacity <= 5){
   properties['size'] = "medium";
 }
 if (car.capacity <= 3){
   properties['size'] = "small";
 }
 return properties;
});
console.log(carsProperties);
// resultado:
// [
//   { capacity: 7, size: 'large' },
//   { capacity: 5, size: 'medium' },
//   { capacity: 5, size: 'medium' },
//   { capacity: 2, size: 'small' },
//   ...
// ]

Adicionando uma propriedade a cada objeto de um array - Array.forEach

E se também quisermos o objeto carro? Nesse caso, aprimoramos o objeto com uma nova propriedade size. Este é um bom caso de uso para a função Array.forEach.

cars.forEach(car => {
 car['size'] = "large";
 if (car.capacity <= 5){
   car['size'] = "medium";
 }
 if (car.capacity <= 3){
   car['size'] = "small";
 }
});

Ordenando um array por propriedade - Array.sort

Quando terminarmos de transformar os objetos, precisaremos ordená-los de uma forma ou de outra.

Tipicamente, a ordenação é baseada no valor de uma propriedade que todos os objetos têm. Podemos usar a função Array.sort, mas precisamos fornecer uma função que defina o mecanismo de ordenação.

Digamos que nossa intenção é ordenar os carros com base em sua capacidade em ordem descendente.

let sortedCars = cars.sort((c1, c2) => (c1.capacity < c2.capacity) ? 1 : (c1.capacity > c2.capacity) ? -1 : 0);
console.log(sortedCars);
// resultado:
// [
//   {
//     color: 'purple',
//     type: 'minivan',
//     registration: 'Wed Feb 01 2017 00:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 7
//   },
//   {
//     color: 'red',
//     type: 'station wagon',
//     registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 5
//   },
//   ...
// ]

O método Array.sort compara dois objetos e coloca o primeiro objeto na segunda posição se o resultado da função de ordenação for positivo. Assim, você pode olhar para a função de ordenação como se ela fosse uma pergunta: o primeiro objeto precisa ser colocado na segunda posição?

sort

Certifique-se de sempre adicionar o caso para zero quando o valor comparado de ambos o objetos for o mesmo para evitar trocas desnecessárias.

Verificando se os objetos em um array atendem a uma condição - Array.every, Array.includes

Array.every e Array.some são úteis quando precisamos apenas verificar se cada objeto atende a uma condição específica.

Temos um conversível (cabrio) vermelho na lista de carros? Todos os carros conseguem transportar pelo menos 4 pessoas? Ou, mais voltado à web: há um produto específico no carrinho de compras da loja?

cars.some(car => car.color === "red" && car.type === "cabrio");
// resultado: true

cars.every(car => car.capacity >= 4);
// resultado: false

Você também pode se lembrar do método Array.includes, que é parecido com Array.some, mas funciona apenas para tipos primitivos.

Resumo

Neste artigo, examinamos as funções básicas que ajudam você a criar, manipular, transformar, e percorrer em laços os arrays de objetos. Isso deve cobrir a maioria dos casos que você encontrará.

Se tiver um caso de uso que exija uma funcionalidade mais avançada, dê uma olhada nesse guia detalhado sobre arrays (em inglês) ou acesse a referência da W3 Schools (em inglês).

Como alternativa, entre em contato com o autor e ele criará um outro artigo sobre o tópico. :-)