Manipulando arrays no Javascript

Manipulando arrays no Javascript
Photo by Faris Mohammed / Unsplash

Entendendo o funcionamento dos métodos some, every, reduce, sort e filter

Você já ouviu falar em programação funcional? Sabe aplicar esses conceitos na linguagem de programação que você utiliza normalmente?

No update desta semana irei abordar e explicar um pouco do funcionamento de algumas higher order functions do Javascript utilizando exercícios práticos que encontrei durante meus estudos.

O array de pessoas a seguir é o que estarei utilizando para os exercícios, ele é uma lista de objetos que representam pessoas, onde cada pessoa tem os atributos name, age e gender.

const people = [
  {
    name: "Matheus",
    age: 22,
    gender: "male"
  },
  {
    name: "Roberto",
    age: 35,
    gender: "male"
  },
  {
    name: "Maria",
    age: 18,
    gender: "female"
  },
  {
    name: "Ana",
    age: 28,
    gender: "female"
  },
  {
    name: "João",
    age: 15,
    gender: "male"
  },
  {
    name: "Clara",
    age: 17,
    gender: "female"
  },
  {
    name: "Enzo",
    age: 10,
    gender: "male"
  }
];

Com base neste array, pense em uma forma de resolver os seguintes problemas:

  • Verificar se todas as pessoas são mulheres.
  • Verificar se há algum homem.
  • Encontrar a pessoa mais jovem.
  • Retornar uma lista ordenando os nomes de a - z.
  • Encontrar pessoas de um gênero específico.

Se você ainda não conhece os métodos every, some, reduce, sort e filter, talvez você tenha pensado que esses problemas tão simples podem ser resolvidos utilizando if / else dentro de alguma estrutura de repetição. Você não está errado, realmente é possível resolver desta forma, mas os métodos que eu citei são uma alternativa mais moderna e elegante de se resolver estes problemas, por isso vamos dar uma olhada em como ficou a minha resolução.

  • Verificar se todas as pessoas são mulheres:
// Verificar se são todas mulheres
function allWomen(people) {
  return people.every(p => p.gender === "female");
}

Simples, não? Com apenas uma linha dentro da função o método every percorre todo o nosso array e vai retornar true ou false de acordo com a função passada como parâmetro, neste caso ela recebe o item atual e verifica se o atributo gender tem o valor "female", a função every retornará true apenas se todos os casos forem verdadeiros. No nosso cenário atual a função retornará false, pois há quatro homens na lista.

  • Verificar se há algum homem na lista:
// Verificar se há algum homem
function hasMen(people) {
  return people.some(p => p.gender === "male");
}

O método some é muito parecido com o every, ele irá percorrer a nossa lista e verificar se a propriedade gender de algum dos objetos tem o valor "male", como já explicado acima,o retorno esperado da função hasMen é true.

  • Encontrar a pessoa mais jovem:
// Encontrar a pessoa mais jovem
function getYoungestPerson() {
  return people.reduce((youngest, p) => {
    return youngest.age < p.age ? youngest.age : p.age;
  }, 999);
}

Neste problema utilizei a função reduce, e neste caso utilizei dois parâmetros. O primeiro é uma função de callback que será aplicada em cada item da lista, a função recebeu dois parâmetros, "min" que é  o acumulador da função, e o parâmetro "p" que é o item atual.

A função reduce precisa receber um segundo parâmetro neste caso, que é o valor inicial do acumulador. Como queremos obter a idade da pessoa mais jovem na lista, eu iniciei a minha variável com o valor 999. Assim que a função começar a percorrer o array ela irá comparar se o atributo age é menor que a variável min, caso a condição seja verdadeira o valor do nosso acumulador vai ser alterado e depois de percorrer  todo o array o objeto onde o valor da propriedade age for menor será retornado.

  • Retornar uma lista ordenando os nomes de a - z:
// Retornar uma lista ordenada de a - z
function orderByName(people) {
  return people.sort((p1, p2) => {
    if (p1.name.toLocaleLowerCase() < p2.name.toLocaleLowerCase()) return -1;
    if (p1.name.toLocaleLowerCase() > p2.name.toLocaleLowerCase()) return 1;
    return 0;
  });
}

O método sort é uma função utilizada para determinar a ordem dos elementos, o único parâmetro necessário aqui é a função de callback para cada item do array, essa função recebe dois parâmetros que são o item anterior e o atual. Por padrão a função sort ordena os items de forma ascendente de acordo com o padrão unicode, por isso utilizei o método toLocaleLowerCase, que converte todos os caracteres em minúsculo para evitar problemas, pois no padrão unicode "Matheus" é diferente de "matheus".

A lógica por trás de tudo isso é bem simples, a função espera que seja retornado um número positivo caso p1 seja menor que p2, um número negativo no caso de p1 ser maior que p2 e zero, no caso deles serem iguais.  Internamente este procedimento será repetido quantas vezes forem necessárias  para o array estar completamente ordenado.

  • Retornar pessoas de um gênero específico:
// Encontrar pessoas de um gênero específico
function getByGender(people, gender) {
  return people.filter(p => p.gender === gender);
}

O último exercício é bem simples, o método filter espera uma função de callback que será usada como condição para determinar quais itens deve estar no nosso novo array.

E aí, curtiu o update desta semana? Se você chegou até aqui deixe nos comentários o que achou ou dê sugestões para novos posts.