This article also exists in: Italian

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

MethodForReturn
.includesReturns true/false if the searched value exists in the arraybool
.findReturns the first element of the array that satisfies the search criterion or undefined if not foundobject|undefined
.filterReturns a new array containing the elements from the original set that satisfy the search criterionArray
.indexOfReturns the first index of the element in the set if it exists, otherwise returns -1Number

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.

About the author

For the last 15 years, Stefano Frasca has worked with a variety of web technologies both backend and frontend. He is currently focused on front-end development. On his day to day job, he is working as a FullStack developer & Frontend dev fan at Immobiliare Labs IT. He has worked remotely for years, passionate about photography, food and code 😎
Do you want to know more? Visit my website!