Etienne Talbot

Siga

Jan 29, 2018 · 7 min de leitura

Se você está iniciando no JavaScript, talvez você ainda não ouviu falar de .map() .reduce() e .filter()., Para mim, demorou um tempo, pois eu tinha que apoiar o Internet Explorer 8 até alguns anos atrás. Mas se você não precisa ser compatível com este navegador muito antigo, você tem que se familiarizar com esses métodos.

note que este artigo provavelmente se aplica a qualquer outra linguagem de programação que você possa estar usando, pois estes são conceitos que existem em muitas outras linguagens.

deixe-me explicar como funciona com um exemplo simples. Digamos que você recebeu um array contendo vários objetos – cada um representando uma pessoa., A coisa que você realmente precisa no final, no entanto, é um array contendo apenas o id de cada pessoa.

vamos comparar!

Usando .forEach():

var officersIds = ;officers.forEach(function (officer) {
officersIds.push(officer.id);
});

Notice how you have to create an empty array before? Vamos ver o que ele procura como quando usando .map():

var officersIds = officers.map(function (officer) {
return officer.id
});

Nós podemos até ser mais conciso com a seta funções (requer ES6 apoio, Babel ou Transcrito)

const officersIds = officers.map(officer => officer.id);

Assim como .map() trabalho?, Basicamente é leva 2 argumentos, um callback e um contexto opcional (será considerado como this no callback) que eu não usei no exemplo anterior. O callback é executado para cada valor no array e retorna cada novo valor no array resultante.

tenha em mente que a matriz resultante será sempre o mesmo comprimento que a matriz original.

.reduzir ()

assim como .map(), .reduce() também executa um callback para cada elemento de um array., O que é diferente aqui é que reduzir passa o resultado desta callback (o Acumulador) de um elemento array para o outro.

O acumulador pode ser praticamente qualquer coisa (inteiro, string, objeto, etc.) and must be instantiated or passed when calling .reduce().

tempo para um exemplo! Digamos que você tem um array com esses pilotos e seus respectivos anos de experiência:

precisamos saber o total de anos de experiência de todos eles., With .reduce(), it’s pretty straightforward:

var totalYears = pilots.reduce(function (accumulator, pilot) {
return accumulator + pilot.years;
}, 0);

Notice that i’ve set the starting value as 0. Eu também poderia ter usado uma variável existente, se necessário. Depois de executar o callback para cada elemento do array, o reduce irá devolver o valor final do nosso acumulador (no nosso caso: 82).

Vamos ver como isso pode ser reduzido com ES6 de seta de funções:

const totalYears = pilots.reduce((acc, pilot) => acc + pilot.years, 0);

Agora vamos supor que eu quero descobrir qual o piloto é o mais experiente., Para isso, eu posso usar reduce as well:

var mostExpPilot = pilots.reduce(function (oldest, pilot) {
return (oldest.years || 0) > pilot.years ? oldest : pilot;
}, {});

I named my accumulator oldest. O meu callback compara o acumulador a cada piloto. Se um piloto tem mais anos de experiência do que oldest, então esse piloto torna-se o novo oldest de modo que este é o que eu retorno.

Como você pode ver, usar .reduce() é uma maneira fácil de gerar um único valor ou objeto a partir de um array.

.filtro ()

e se você tiver um array, mas só quiser alguns dos elementos nele?, É onde .filter() entra!

Aqui estão os nossos dados:

digamos que queremos duas matrizes agora: uma para pilotos rebeldes, a outra para imperiais. Com .filter() não poderia ser mais fácil!é isso! E é ainda mais curto com as funções arrow:

const rebels = pilots.filter(pilot => pilot.faction === "Rebels");
const empire = pilots.filter(pilot => pilot.faction === "Empire");

basicamente, se a função callback retornar verdadeiro, o elemento atual será na matriz resultante. Se devolver falso, não será.combinação.mapa(), .reduzir(), e .,filtro ()

Uma vez que todos os três são chamados em matrizes e desde .map() e .filter() ambas as matrizes de retorno, podemos facilmente acorrentar as nossas chamadas.vamos ver outro exemplo. Aqui estão os nossos dados:

nosso objetivo: obter a pontuação total de Usuários de força apenas. Vamos fazê-lo passo a passo!

primeiro, precisamos filtrar o pessoal que não pode usar a força:

var jediPersonnel = personnel.filter(function (person) {
return person.isForceUser;
});// Result: (Luke, Ezra and Caleb)

com que temos 3 elementos deixados em nossa matriz resultante. Agora precisamos de criar uma matriz contendo a pontuação total de cada Jedi.,

var jediScores = jediPersonnel.map(function (jedi) {
return jedi.pilotingScore + jedi.shootingScore;
});// Result:

E vamos reduzir para obter o total de:

var totalJediScore = jediScores.reduce(function (acc, score) {
return acc + score;
}, 0);// Result: 420

E agora aqui é a parte divertida… podemos cadeia de tudo isso para conseguir o que deseja em uma única linha:

E olhe o quão bonito é com a seta funções:

Boom! nota: no meu exemplo anterior, .map()e.filter() nem sequer eram necessários. Poderíamos facilmente alcançar o mesmo resultado com apenas .reduce(). Deixei-os lá por causa deste exemplo., Você pode adivinhar como nós só poderíamos manter .reduce() e obter o mesmo resultado com uma linha de código? Ver a solução no Codepeno

por que não utilizar .forEach()?

i used to use for loops everywhere instead of .map(),.reduce(), and.filter(). Mas alguns anos atrás eu comecei a trabalhar muito mais com dados que vieram de uma API. Foi aí que comecei a ver as vantagens de deixar .forEach para trás.,

formatação

diga que precisa de mostrar uma lista de pessoas, com o seu nome e título de trabalho.

var data = 

a API dá-lhe os dados acima, mas você só precisa do título e do sobrenome de cada pessoa… você precisa formatar os dados. No entanto, o seu aplicativo também precisa ter uma única vista para cada pessoa, então você deve escrever uma função de formatação de dados que ambos funciona em uma lista e em uma única vista.,

isso significa Que você não pode ter o .forEach loop dentro de sua função de formatar, ou então você teria que envolver o seu único elemento em uma matriz antes de passar para a função apenas para torná-lo trabalhar, assim:

var result = formatElement();
// Yeah... that's not right at all

Então, o ciclo tem para encapsular a chamada da função, como este:

data.forEach(function (element) {
var formatted = formatElement(element);
// But what then....
});

Mas .forEach() não retorna nada. Isso significa que tens de introduzir os resultados dentro de uma matriz pré-determinada.,

var results = ;data.forEach(function (element) {
var formatted = formatElement(element);
results.push(formatted);
});

como resultado, você tem 2 funções: sua função formatElement() e sua função que empurra os resultados em sua matriz.

Por que ter 2 funções quando você pode ter apenas uma?

var results = data.map(formatElement);

Teste é mais fácil

Se você escrever testes de unidade para o seu código, você vai encontrá-lo mais simples para testar as funções de chamada com .map() .reduce(), ou .filter().

tudo o que você tem a fazer é fornecer dados de entrada para a função e esperar um resultado para sair., Basicamente, ” o que sai se isto for aprovado?”. Menos manipulação, menos beforeEach()s e afterEach()s. É simples, simples teste.tenta!

Se gostou desse artigo e quer aprender mais métodos de array, confira o meu artigo sobre como usar .some() e .find() em JavaScript.continue a codificar!

Articles

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *