In frontend environment, especially working closely with JS, it happens most of the time to use Array to store data.
const _var = ['π€','π½','β οΈ','π
','π¨','π§','π'];
And very often it is necessary to search for elements within this dataset: you may need to find the index of the element, or simply know if the element is present⦠or get a subset of elements that meet a certain criterion.
With the advent of ES6, many methods for Array searches have been introduced.
Useful array search methods
Method | For | Return |
---|---|---|
.includes | Returns true/false if the searched value exists in the array | bool |
.find | Returns the first element of the array that satisfies the search criterion or undefined if not found | object|undefined |
.filter | Returns a new array containing the elements from the original set that satisfy the search criterion | Array |
.indexOf | Returns the first index of the element in the set if it exists, otherwise returns -1 | Number |
Quindi
- I need to find if an element is present in an array: I can use .includes() directly, or check that .find() is different from
undefined
, or check that .indexOf() is different from -1 - I need to find the exact index of where the element is present: undoubtedly the .indexOf() is the best method
- I need exactly the item which respects criteria within the array: .find() or .filter() in case of multiple values (subset)
Is the element present in the array?
const people = ['π€','π½','β οΈ','π
','π¨','π§','π'];
//using includes
let isKoalaPresent = people.includes('π¨');
//using find
let isAlienPresent = typeof (people.find((el) => el === 'π½')) !== 'undefined';
//using indexOf
let isRobotPresent = people.indexOf('π€') !== -1;
For example, one need might be to add a Clown after Santa Claus in our dataset. Basically, we would need to find the location of Santa Claus and place the Clown afterwards.
Index of an element in the dataset
let people = ['π€','π½','β οΈ','π
','π¨','π§','π'];
let santaClausPosition = people.indexOf('π
'); //3
// splice: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice?retiredLocale=it
// position of π€‘ is after π
, so ++santaClausPosition
people.splice(++santaClausPosition, 0, 'π€‘');
console.log(people);
//['π€','π½','β οΈ','π
','π€‘','π¨','π§','π']
tldr
Although both santaClausPosition++ and ++santaClausPosition increment the variable to which they are applied, the result returned by santaClausPosition++ is the value of the variable before of the increment, while the result returned by ++santaClausPosition is the value of the variable after that the increment was applied.
tips
.indexOf can return the index of the element in an array also starting from a certain position: in this case itβs enough to pass an integer as second parameter of the method. Moreover, if you want to start the search not from the beginning but from the end, there is the .lastIndexOf method
let people = ['π€','π½','β οΈ','π
','π¨','π§','π
','π'];
let santaClausPosition = people.indexOf('π
', 4); //6
Elements from array
Suppose we have a dataset that represents rooms with entities inside.
let environment = [
{
name: 'Space Room',
people: ['π½','π€','πΎ'],
type: 'ROBOT_ALIEN',
},
{
name: 'Animal Court',
people: ['π¨','π§'],
type: 'ANIMAL',
},
{
name: 'Attention Field',
people: ['π','β οΈ','πΎ'],
type: 'SKULL',
},
{
name: 'Magic Room',
people: ['π
','π€‘'],
type: 'MAGIC',
}
];
I would like to find the room related to animals.
let animalsRoom = environment.find((room) => room.type === 'ANIMAL');
console.log(animalsRoom);
/*
{
name: 'Animal Court',
people: ['π¨','π§'],
type: 'ANIMAL'
}
*/
// NB: `(room) => room.type === 'ANIMAL'` is the search criteria.
// If the criterion for room, returns true then room
// is an element accepted by the find.
Maybe instead Iβd really like the room where the Alien is presentβ¦
let alienRoom = environment.find((room) => room.people.includes('π½'));
console.log(alienRoom);
/*
{
name: 'Space Room',
people: ['π½','π€','πΎ'],
type: 'ROBOT_ALIEN'
}
*/
In case we want to get a subset of data instead we could use .filter(). To go deeper you can also see it in action here.
Actually even though it has been covered in a previous article, I would like to show it in action by combining it with concat(), to get a flatten array from multiple data sources. For example I would like to get all the robots that may be present in the various rooms.
let filterRobot = (el) => el.includes('π€') || el.includes('πΎ');
let robotPeoples = environment.filter((room) => filterRobot(room.people))
.map((el) => el.people.filter((entity) => filterRobot(entity)));
let robots = [].concat.apply([], robotPeoples);
console.log(robots);
//['π€', 'πΎ', 'πΎ']
In this article we have seen, also through some practical examples, a basic approach to the *search of elements in arrays with Javascript ES6+.
By combining Array.filter(), Array.find(), Array.includes(), Array.indexOf() with .map() and .reduce() we have a very powerful toolset for manipulating data on Array.