📜 ⬆️ ⬇️

Effective use of array methods in javascript

The author of the material, the translation of which we publish today, says that in the past few months, when checking pull requests, he always came across the same four shortcomings related to the irrational use of array methods in JavaScript. In order for such flaws in the code, which had previously appeared in his programs, become less, he wrote this article.



Replacing indexOf () with includes ()


"If you are looking for something in an array, use the indexOf() method." Something like this recommendation I met at one of the courses when I was learning JavaScript. The recommendation is quite normal, nothing bad can be said about it.

On MDN, you can see that the indexOf() method returns the first index by which an element can be found in the array. This means that if we plan to use this index in the program, the indexof() method is excellent for searching elements in arrays.
')
But what if we just need to find out if there is a certain element in the array or not? That is, we are not interested in the index of this element, if it is in the array, but in the fact of its presence or absence. With this approach, we are quite satisfied with the command that returns true or false . In such cases, I recommend using not the indexOf() method, but the includes() method, which returns a boolean value. Consider an example:

 'use strict'; const characters = [ 'ironman', 'black_widow', 'hulk', 'captain_america', 'hulk', 'thor', ]; console.log(characters.indexOf('hulk')); // 2 console.log(characters.indexOf('batman')); // -1 console.log(characters.includes('hulk')); // true console.log(characters.includes('batman')); // false 

Using the find () method instead of the filter () method


The filter() method is a very useful tool. He, on the basis of one array, creates another array containing the elements of the source array corresponding to the given condition. As can be understood from the name of this method, it is intended for filtering arrays, during which arrays are usually obtained that are shorter than the original ones.

What if we know that after filtering the array, only one element will remain? For example, this can happen when trying to filter the elements of an array based on some unique identifier. In such a situation, I would not advise using the filter() method, since the array that it forms will contain only one element. If we are interested in an array element with a unique value, then we are going to work with a single value, and to represent such a value, the array is not needed.

If we talk about the performance of the filter() method, then it turns out that in order to form a list of the elements corresponding to the condition specified when it was called, you will have to look through the entire array. Moreover, imagine that there are hundreds of elements in an array that satisfy a given condition. This will result in the resulting array being rather large.

In order to avoid getting into such situations, I would advise using the find() method. When called, it is passed a callback describing a condition very similar to that used with the filter() method, but the find() method returns only the first element that matches the condition. In this case, this method stops working immediately after it finds such an element. The entire array to him, in the end, do not have to browse.

 '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' } 

Replacing the find () Method with the Some () Method


I have to admit that the mistake that we will discuss now, I have committed many times. Then I was advised to look at MDN and see how to improve what I was doing irrationally. In a nutshell, this is very similar to what we have just discussed, referring to the methods indexOf() and includes() .

In the above case, we saw that the find() method, as an argument, takes a callback and returns an array element. Is it possible to call the find() method the most successful solution if we need to find out if the array contains some value or not? Perhaps - no, because this method returns the value of an element of the array, rather than a logical value.

In this situation, I would recommend using the some() method, which returns a boolean value.

 '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'))); // { id: 1, name: 'ironman', env: 'marvel' } console.log(characters.some(hasCharacterFrom('marvel'))); // true 

Using the reduce () method instead of a combination of the filter () and map () methods


It is worth saying that the reduce() method cannot be attributed to simple to understand. However, if what can be done with it is done in two steps, using the filter() and map() methods that are chained, it seems that something in this approach is wrong.

I say that with this approach, the array must be viewed twice. The first pass performed by the filter() method involves viewing the entire array and creating a new, filtered array. After the second pass, performed by the map() method, again, a new array is created, which contains the results of the transformation of the array elements obtained after the filter() method works. As a result, in order to enter the finished array, two methods are used. Each method has its own callback, while creating such an operation using the filter() method creates an array with which we can no longer work.

In order to reduce the load on the system created by using two methods and to improve the performance of programs, in such cases I would advise using the reduce() method. The result will be the same, and the code will turn out better. This method allows you to filter the elements of interest to us and add them to the battery. A battery can be a numeric variable that stores, say, the sum of the elements of an array, it can be an object, a string, or an array in which we can accumulate the elements we need.

In our case, since we are talking about using the map() method, I would advise using the reduce() method with an array as a battery. In the following example, we filter the elements of the array, which are objects, by the value of the env field, and perform their conversion.

 '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'] } // ] 

Results


In this material, we examined some approaches to the effective use of array methods in solving various problems. We believe that the ideas on which the recommendations given by the author of this article are based may help in improving the JS code in other situations.

Dear readers! Have you ever met with examples of the unsustainable use of JavaScript mechanisms?

Source: https://habr.com/ru/post/422091/


All Articles