O autor do material, cuja tradução publicamos hoje, diz que nos últimos meses, ao verificar solicitações pull, ele constantemente se deparava com as mesmas quatro falhas associadas ao uso irracional de métodos de matriz em JavaScript. Para reduzir essas falhas de código que apareceram anteriormente em seus programas, ele escreveu este artigo.

Substituindo indexOf () por includes ()
"Se você está procurando algo em uma matriz, use o método
indexOf()
." Eu conheci essa recomendação em um dos cursos quando estudei JavaScript. Esta recomendação é bastante normal, nada de ruim pode ser dito sobre isso.
No MDN, você pode descobrir que o método
indexOf()
retorna o primeiro índice pelo qual um determinado elemento pode ser encontrado na matriz. Isso significa que, se planejamos usar esse índice no programa, o método
indexof()
é ótimo para encontrar elementos em matrizes.
Mas e se apenas precisarmos descobrir se existe um determinado elemento na matriz ou não? Ou seja, não estamos interessados no índice desse elemento, se ele estiver na matriz, mas no fato de sua presença ou ausência. Com essa abordagem, estamos bastante confortáveis com um comando que retorna
true
ou
false
. Nesses casos, eu recomendo não usar o método
indexOf()
, mas o método
includes()
, que retorna um valor booleano. Considere um exemplo:
'use strict'; const characters = [ 'ironman', 'black_widow', 'hulk', 'captain_america', 'hulk', 'thor', ]; console.log(characters.indexOf('hulk'));
Usando o método find () em vez do método filter ()
O método
filter()
é uma ferramenta muito útil. Com base em uma matriz, cria outra matriz contendo os elementos da matriz original que correspondem à condição especificada. Como pode ser entendido pelo nome desse método, ele se destina a filtrar matrizes, durante as quais geralmente são obtidas matrizes mais curtas que as originais.
E se soubermos que depois de filtrar a matriz, apenas um elemento permanecerá? Por exemplo, isso pode acontecer quando você tenta filtrar elementos da matriz com base em algum identificador exclusivo. Em tal situação, eu não recomendaria o uso do método
filter()
, pois a matriz que ele forma conterá apenas um elemento. Se estivermos interessados em um elemento da matriz com um valor único, trabalharemos com um único valor, e uma matriz não é necessária para representar esse valor.
Se falamos sobre o desempenho do método
filter()
, verifica-se que, para formar uma lista de elementos correspondentes à condição especificada quando foi chamada, seria necessário examinar toda a matriz. Além disso, imagine que existem centenas de elementos em uma matriz que satisfazem uma determinada condição. Isso resultará na matriz resultante muito grande.
Para evitar entrar em tais situações, eu recomendaria o uso do método
find()
. Quando chamado, recebe um retorno de chamada descrevendo a condição, muito semelhante ao usado com o método
filter()
, mas o método
find()
retorna apenas o primeiro elemento que corresponde à condição. Ao mesmo tempo, esse método para de funcionar imediatamente após encontrar esse elemento. Como resultado, ele não precisa procurar a matriz inteira.
'use strict'; const characters = [ { id: 1, name: 'ironman' }, { id: 2, name: 'black_widow' }, { id: 3, name: 'captain_america' }, { id: 4, name: 'captain_america' }, ]; function getCharacter(name) { return character => character.name === name; } console.log(characters.filter(getCharacter('captain_america'))); // [ // { id: 3, name: 'captain_america' }, // { id: 4, name: 'captain_america' }, // ] console.log(characters.find(getCharacter('captain_america'))); // { id: 3, name: 'captain_america' }
Substituindo o método find () pelo método some ()
Devo admitir que cometi muitas vezes a supervisão que discutiremos agora. Então eles me aconselharam a olhar para o
MDN e ver como melhorar o que eu fazia irracionalmente. Em poucas palavras, isso é muito semelhante ao que acabamos de ver quando falamos sobre os métodos
indexOf()
e
includes()
.
No caso acima, vimos que o método
find()
, como argumento, recebe um retorno de chamada e retorna um elemento da matriz. O método
find()
ser chamado de solução mais bem-sucedida se precisarmos descobrir se a matriz contém um determinado valor ou não? Talvez não, pois esse método retorna o valor de um elemento da matriz, não um booleano.
Em tal situação, eu recomendaria usar o método
some()
, que retorna um valor booleano.
'use strict'; const characters = [ { id: 1, name: 'ironman', env: 'marvel' }, { id: 2, name: 'black_widow', env: 'marvel' }, { id: 3, name: 'wonder_woman', env: 'dc_comics' }, ]; function hasCharacterFrom(env) { return character => character.env === env; } console.log(characters.find(hasCharacterFrom('marvel')));
Usando o método reduzir () em vez de uma combinação dos métodos filter () e map ()
Vale dizer que o método
reduce()
não pode ser classificado como fácil de entender. No entanto, se o que pode ser feito com isso for feito em duas etapas, usando os métodos
filter()
e
map()
combinados em uma cadeia, parece que algo nessa abordagem está errado.
Eu digo que, com essa abordagem, você precisa olhar o array duas vezes. A primeira passagem, realizada pelo método
filter()
, envolve a exibição de toda a matriz e a criação de uma nova matriz filtrada. Após a segunda passagem, realizada pelo método
map()
, novamente, é criada uma nova matriz que contém os resultados da transformação dos elementos da matriz obtidos após a execução do método
filter()
. Como resultado, para alcançar a matriz finalizada, dois métodos são usados. Cada método possui seu próprio retorno de chamada e, durante a execução de uma operação usando o método
filter()
, é criada uma matriz com a qual não podemos mais trabalhar.
Para reduzir a carga no sistema criado usando dois métodos e aumentar a produtividade dos programas, nesses casos, eu recomendaria o uso do método
reduce()
. O resultado será o mesmo, mas o código ficará melhor. Este método permite filtrar os elementos de interesse para nós e adicioná-los à bateria. A bateria pode ser uma variável numérica que armazena, digamos, a soma dos elementos da matriz, pode ser um objeto, uma string ou uma matriz na qual podemos acumular os elementos de que precisamos.
No nosso caso, como estamos falando sobre o uso do método
map()
, eu recomendaria o uso do método
reduce()
com uma matriz como um acumulador. No exemplo a seguir, filtramos os elementos da matriz que são objetos pelo valor do campo
env
e realizamos sua conversão.
'use strict'; const characters = [ { name: 'ironman', env: 'marvel' }, { name: 'black_widow', env: 'marvel' }, { name: 'wonder_woman', env: 'dc_comics' }, ]; console.log( characters .filter(character => character.env === 'marvel') .map(character => Object.assign({}, character, { alsoSeenIn: ['Avengers'] })) ); // [ // { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] }, // { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] } // ] console.log( characters .reduce((acc, character) => { return character.env === 'marvel' ? acc.concat(Object.assign({}, character, { alsoSeenIn: ['Avengers'] })) : acc; }, []) ) // [ // { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] }, // { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] } // ]
Sumário
Neste artigo, examinamos algumas abordagens para o uso eficaz de métodos de matriz na solução de vários problemas. Acreditamos que as idéias nas quais as recomendações dadas pelo autor deste artigo podem ajudar a melhorar o código JS em outras situações.
Caros leitores! Você já encontrou exemplos de má alocação de mecanismos JavaScript?
