We will see the 3 to 5 frequently used array functions in JavaScript.

Now why did I list these in quirks ?

I personally say that JavaScript is very quirky and I don’t use this functions often as I don’t like to remember stuff and I never understood how exactly some of them works. On a standard POV this is necessary but I will still say these are quirky ways of writing a loop !

We will be looking at

  • array.forEach()
  • array.map()
  • array.filter()
  • array.reduce()

The .forEach() function

The .forEach() works very similar to a for loop running from the first element to the last !

Syntax: array.forEach(callback_function)

const arr = ["Peach", "Mango", "Banana"];

arr.forEach(item => console.log(item));

.forEach() automatically calls the callback function we passed to it ! The .forEach() returns nothing.


The .map() function

The .map() function loops over an array and returns a new array based on the callback provided.

Syntax: new_array = array.map(callback_function)

const arr = [2, 3, 4, 5];

const two_added = arr.map(item => item + 2);

console.log(two_added); //prints [4, 5, 6, 7]

.map() loops through each element in arr and for each element, stored in item it is added by 2 and the result is used in the new array creation (two_added in this case).

Lets Look at another Example:

const arr = ["C++", "Java", "Python"];

const obj = arr.map((item, index) => {
  return { [index] : item };
});

console.log(obj);

Here we are making an array of objects with the index from arr as the key and the values from arr as the value.

We used [index] in the third bracket because its called Computed Property Name, its used when the key of an object is needed to come from a variable.

Also the .map() gives us the index of each element too as a second parameter to the callback !


The .filter() function

The .filter() loops through an array and keeps only the items that pass a test.

Syntax: const new_array = array.filter(callback_function)

Lets directly see it in work :

const arr = [1, 2, 3, 4, 5, 6, 7, 8];
const evens = arr.filter(item => item % 2 === 0);

console.log(evens); //prints [2, 4, 6, 8]

This literally looks like a if-else inside a for loop. That’s it !

It returns an new array based on a test. Key observation is that since it works on a test then the callback should return a boolean value, i.e. true (1) or false (0). BUT….. .filter() does not care what the callback returns, it actually treats values as Truthy or Falsy. So if the current item based on the test returns a Truthy value it is kept, else is rejected !

Some examples of Falsy values are : undefined , "" , null, NaN, 0, etc.

Lets see another example this time with a mix of .map() :

const arr = [1, 2, 3, 4, 5, 6, 7, 8];

const doubled_evens = arr.filter(number => number % 2 === 0).map(item => item * 2);

console.log(doubled_evens); //prints [4, 8, 12, 16]

The question was to create an array with only even numbers doubled from arr.

First we filter out the even numbers from arr using .filter() the condition used is to check weather the number is even of not if truthy we add it in the array ! Now from the new array we chain .map() to double them and finally print the new array.


The .reduce() function

This one is a wild value accumulator !

Loops through an array and accumulate values as required in the callback function.

Syntax: array.reduce((accumulator, current_value) => function_body, initial_value)

const arr = [1, 2, 3, 4, 5];

const sum = arr.reduce((acc, val) => acc + val, 1);

console.log(sum); //prints 15

The first param is the accumulator which is by default the first element of the array, the value is the current element the in the loop and the rest is the function body. Here the acc works by accumulating values i.e. acc is updated on every iteration, calculated through acc + val. Its the same as doing acc += val ! We can also pass a third parameter which is the index of the array !

An additional initial value can be passed after function body to define what acc should be at the start.

Lets look at another example (building .map() using .reduce()):

const arr = [1, 2, 3, 4, 5];

const doubled_arr = arr.reduce((acc, value) =>{
	acc.push(value * 2);
	return acc;
}, []);

console.log(doubled_arr);

This is a simple example where I create .map() using .reduce() ! Now still just a loop, we start from [] and then for each element we just push value * 2 into acc and then return it, that’s it ! And this is .map()’s behavior, output an array (acc in this case) based on the callback value * 2 !


Final Thoughts

These still are just loops made to look funky ! These still runs in O(n) time complexity, same as a for or while loop will run in.

Me personally will still stick to traditional loops and only use these if the logic is really easy to understand and small. For bigger and more complex logics, traditional loops are kings whether it be case of readability or control !

…And will use them in Job Interviews as interviewers love to chain a bunch of this funky functions and say “Yeah what will be the output”, even they themselves don’t know what the actual f#ck is going on !

Check out other JS quirks here: Quirk Index