Diving into Array.prototype.map, Array.prototype.find, and Array.prototype.some

Daniel Ebron
12 min readApr 2, 2022

Array.prototype.map

map, find, and some are helpful JavaScript methods aimed at dealing with Arrays. To begin, let us first define some important terms.

Higher Order Function : a function that accepts other functions as an argument, or, a function that returns other functions.

[1, 2, 3].map(num => num * 2);

Callback function : more simply, callback, is a function that is passed to other functions.

[1, 2, 3].map(num => num * 2);

Now let’s take a look at the map method in action:

[1, 2, 3].map(num => num * 2);// Map Returns
// [2, 4, 6]

In the above, we are working with array [1, 2, 3], a map method (Higher Order Function), and an arrow function (Callback).

When we call map on array [1, 2, 3], an iteration begins and each value of the current element is used as an argument to invoke the callback. Bear in mind that this argument is represented in the arrow function by the parameter named num.

When the code within the callback num * 2 is executed for each iteration, we get [2, 4, 6] which map returns as a new array.

Below, we can see evidence of map returning a new array:

let originalArray = [1, 2, 3];
let mapValues = originalArray.map(num => num * 1);
originalArray[2] = 99;
console.log(mapValues); //Logs [1, 2, 3]
console.log(originalArray); //Logs [1, 2, 99]

On line 1, we have a global variable declaration named originalArray that is initialized with a reference to the[1, 2, 3] array. On line 2, we declare another global variable named mapValues, which captures the return value of calling the map method on originalArray; the reference to [1, 2, 3] array.

We then mutate originalArray (line 3) by reassigning the value of its element at index 2 - by use of bracket notation - to the number literal 99.

As a result, when we call console. log using the reference originalArray as an argument (line 5), what prints to the console is a mutated array [1, 2, 99].

When we call console.log using the reference mapValues as an argument on the other hand - since map returns a new array - the console output is still a reference to the original [1, 2, 3] array.

In a few short lines of code, we’ve proven that map returns a new array. Now let’s move on to the next topic.

Return Value of map Callback

Note the importance of the return value of the callback; the transformation criterion for map. Let’s look at a few examples.

Example 1: console.log as the return value

let mapValues = [1, 2, 3].map(num => console.log(num * 1));
console.log(mapValues);
// Console Prints **
// 1
// 2
// 3
// Return Value** console.log(mapValues)
// [undefined, undefined, undefined]

The return value of the callback num =>console.log(num * 1), logs to the console 1, 2, 3, and map returns an array of undefined [undefined, undefined, undefined]as a result of the callback that returns console.log on each iteration of [1, 2, 3]; referenced by mapValues.

(console.log implicitly returns undefined since it does not explicitly return anything)

Example 2: Missing return statement inside Curly Braces {}

let mapValues = [1,2,3].map(num => {
num * 1;
});
console.log(mapValues); // Logs [undefined, undefined, undefined]

In the above, notice how a missing return statement - especially when combined with the use of curly braces ( line 1 to line 3) - returns undefined.

Because the return value of the map callback will determine the new array it returns, a missing return statement will return undefined for each element of array[1, 2, 3]; making up the new array that map returns.

[undefined, undefined, undefined]

Example 3: Boolean as the return value


let originalArray = [1, 2, 3];
let mapValues = originalArray.map(num => (num * 1 !== 0) );
console.log(mapValues); // Logs [true, true, true]

In this example, the return value of the callback of map is boolean, so map will return an new array of booleans

map with Strings

There is no map method for strings, so we have to take another approach in the form of .split(), and .join(). Take for example, the code below.

let str = "I'll be back";
let stringToArray = str.split('');
str = stringToArray.map(char => char + char)
.join('');
console.log(stringToArray);
// Logs [ 'I', "'", 'l', 'l',' ', 'b', 'e', ' ', 'b', 'a', 'c', 'k']
console.log(str); // Logs II''llll bbee bbaacckk

On line 2, we use .split(‘’) to turn the value of str into an array of characters and reference that array to stringToArray variable. In order to use map, since it is an array method, this step is crucial.

On line 3, we then call map on stringToArray where for each iteration, we use the arrays elements as an argument in the callback char => char + char; the return value of which, is returned by map to a new array.

On line 4, we then use .join(‘’) to combine the array returned by map resulting in II’’llll bbee bbaacckk as the new the value in the reassignment of str on line 3.

Notice that in both .split() and .join() we use an empty string ’’ as an argument, which means that we are splitting and joining, respectively, using each characters of the string (see line 6).

map with Objects

Similar to working with strings, when using map with Objects, we need to take another approach. In this section, we will be looking into Object.keys, Object.values, and Object.entries ; methods that convert objects to arrays, which make them useable, for instance, in our map method.

Lets first take a look at Object.keys method:

let sport = {
basketball: ‘Kobe Bryant’,
boxing: ‘Manny Pacquiaw’,
soccer: ‘Christiano Ronaldo’,
golf: ‘Tiger Woods’
};
let sportType = Object.keys(sport); //Line 8
let sportLogged = sportType.map(sports => console.log(sports));
console.log(sportLogged);// prints
basketball
boxing
soccer
Golf
//returns
//[undefined, undefined, undefined, undefined]

On line 8, we are calling Object.keys passing through it as an argument, the object referenced by sport, which returns an array made up of strings representing the keys (key-value pair) of the sport object.

[‘basketball’, ‘boxing’, ‘soccer’, ‘Golf’].

These values, which will be used by map, is referenced by the variable named sportType.

In the next line, we are calling map on the array referenced by sportType, which if we remember clearly, will return a new array based on the return values of the callback. Since our callback return value is console.log, we know that after printing its sports argument (see line 9), map will return a new array of undefined

[undefined, undefined, undefined, undefined] .

Lets see the code again using the Object.values() method:

let sport = {
basketball: ‘Kobe Bryant’,
boxing: ‘Manny Pacquiaw’,
soccer: ‘Christiano Ronaldo’,
Golf: ‘Tiger Woods’
}
let sportPlayers = Object.values(sport); //Line 8
let playersLogged = sportPlayers.map(players => console.log(players))
console.log(playersLogged)// prints
Kobe Bryant
Manny Pacquiaw
Christiano Ronaldo
Tiger Woods
//returns
//[undefined, undefined, undefined, undefined]

On line 8, we are using Object.values(), passing through it as an argument, the object referenced by sport, which returns an array [‘Kobe Bryant’, ‘Manny Pacquiaw’, ‘Christiano Ronaldo’, ‘Tiger Woods’]; the values of sport object. Note that this array is referenced by the sportPlayers variable.

On line 9, we then call map on sportPlayers and on each iteration, our callback return of console.log will print Kobe Bryant, Manny Pacquiaw, Christiano Ronaldo, Tiger Woods, and return [undefined, undefined, undefined, undefined]; the values of which, are referenced by playersLogged variable.

Lastly, let’s take a look at Object.entries() method.

let sport = {
basketball: ‘Kobe Bryant’,
boxing: ‘Manny Pacquiaw’,
soccer: ‘Christiano Ronaldo’,
Golf: ‘Tiger Woods’
}
let sportPlayersPair = Object.entries(sport); //Line 8
let sportPlayersPairLogged = sportPlayersPair.map(pair => console.log(pair));
console.log(sportPlayersPairLogged);// prints
[ ‘basketball’, ‘Kobe Bryant’ ],
[ ‘boxing’, ‘Manny Pacquiaw’ ],
[ ‘soccer’, ‘Christiano Ronaldo’ ],
[ ‘Golf’, ‘Tiger Woods’ ]
//returns
//[ undefined, undefined, undefined, undefined ]

When we call Object.entries() and pass through it as an argument, the object referenced by sport, we get a return of all the key-value pairs of object sport in an array.

[
[ ‘basketball’, ‘Kobe Bryant’ ],
[ ‘boxing’, ‘Manny Pacqiaw’ ],
[ ‘soccer’, ‘Christiano Ronaldo’ ],
[ ‘Golf’, ‘Tiget Woods’ ]
]

Notice that this array is referenced by sportPlayersPair variable (line 8).

Like we have seen before, the return of the callback (console.log)through calling map on sportPlayersPair will first print,

[ ‘basketball’, ‘Kobe Bryant’ ] 
[ ‘boxing’, ‘Manny Pacquiaw’ ]
[ ‘soccer’, ‘Christiano Ronaldo’ ]
[ ‘Golf’, ‘Tiger Woods’ ]

and then return

[ undefined, undefined, undefined, undefined ]

which is the value that will be referenced by sportPlayersPairLogged, as a result of map returning a new array.

Array.prototype.find

Understanding map will serve us well in understanding find, another JavaScript method.

Before diving deeper into that though, lets first remember the values that JavaScript evaluates to false:

‘’, undefined, null, NaN, 0 & false

This knowledge will prove useful in our understanding of find. Now, let’s dive in!

[1, 2, 3, 4, 5].find(num => num > 2)// Find Returns
// 3

find passes each element of the array its called on to its callback as an argument, returning only the first element value that evaluates to true within that callback.

In our example, the return value of callback num => num > 2 is false when the value of num is 1 and 2. However, when value of num is 3, the return value of the callback is true; which is why 3 is what find returns.

Note that when the value of num is 4 or 5, the callback also returns true but since we only care for the first instance of the callback returning true, 4 and 5 will not be returned.

[1, 2, 3, 4, 5].find(num => num < 0)// Find Returns
// undefined

In the above, we can see that if a callback doesn’t return a truthy value for any of the elements being used as an argument, find will return undefined.

To get a better understanding of find, lets take a look at a few more examples:

Example 1: ‘hi’

let evaluatesToTrue = [1, 2, 3, 4, 5].find(num => ‘hi’);console.log(evaluatesToTrue) // Logs 1

When we call find using [1, 2, 3, 4, 5] array, its elements are being used as arguments in the num => ‘hi’ callback. Essentially, any value of num in this callback will evaluate to true since 'hi' is NOT one of the values that JavaScript implicitly treats as false. With find, we only care about the first value that evaluates to true, so on the first iteration of the array when the value of num is 1, find returns it and ends execution.

Note that this value is captured in the variable evaluatesToTrue .

Example 2: num + 1

let evaluatesToTrue = [1, 2, 3, 4, 5].find(num => num + 1);console.log(evaluatesToTrue) // Logs 1

Let’s take a step by step look at this example using what we know about find. On the first iteration, find passes the array element 1, to the callback as an argument.

When num represents 1, this is how our callback looks:

1 => 1 + 1

When 1 is passed as an argument, we get a return value of 2 - which evaluates to true - meaning, that this value of num is the first and only value that find will return. Notice that just like the previous example, any value of num in this circumstance will evaluate to true, but with find, we care only about the first .

Lets take another example: num — 1

let evaluatesToFalse = [1, 2, 3, 4, 5].find(num => num - 1);console.log(evaluatesToFalse);

Let’s take the same approach as before in understanding the code above.

On the first iteration, find passes the array element 1, to the callback as an argument.

When num represents 1, this is how our callback looks:

1 => 1 - 1

When 1 is passed as an argument, we get a return value of 0 which evaluates to false. Remember the falsy values of JavaScript?

In this case, find moves to the next iteration in the array and assigns element 2, as the next argument to the callback.

2 => 2 - 1

When 2 is passed as an argument, we get a return value of -1 which - since its NOT one of the values that JavaScript treats as false - evaluates to true.

In this scenario, find returns 2, which is initialized to the evaluatesToFalse variable.

Example 3: console.log

let evaluatesToWhat = [1, 2, 3, 4, 5].find(num => console.log(num + 1));console.log(evaluatesToWhat);// evaluatesToWhat Prints ***
3
2
5
4
6
// evaluatesToWhat Returns ***
undefined

In this example, let’s use what we’ve learned about using console log as a return value in a callback. Remember, console.log implicitly returns undefined

For each value of num, console.log will return undefined , print to the console the return value of num + 1 and move to the next iteration, eventually, returning undefined. To reiterate, since there are no values of num here that evaluates to true, find will return undefined.

Example 4: Working with strings

let str = “I’ll be back”;
let stringToArray = str.split(‘’);
str = stringToArray.find(char => char === ‘k’)
console.log(stringToArray);
// Logs [ ‘I’, “‘“, ‘l’, ‘l’,’ ‘, ‘b’, ‘e’, ‘ ‘, ‘b’, ‘a’, ‘c’, ‘k’]
console.log(str); // k

Notice the use of .split() (line 2) allowing us to take advantage of find.

Example 5: Working with objects

let sport = {
basketball: 0,
boxing: ‘Manny Pacquiaw’,
soccer: ‘Christiano Ronaldo’,
Golf: 0
}
let sportPlayersPair = Object.values(sport); //Line 8
let sportPlayersPairLogged = sportPlayersPair.find(values => values);
console.log(sportPlayersPairLogged);
Manny Pacquiaw

On line 8, sportPlayersPair is referencing the array

[ 0, 'Manny Pacquiaw', 'Christiano Ronaldo', 0 ]

In this example, remember that 0 is a falsy value that find will move forward from.

The next iteration on the other hand Manny Pacquiaw, is NOT a falsy value and therefore WILL be returned by find.

Array.prototype.some

Now that we have a firm grasp on map and find, let’s take a look at some.

let trueOrFalse = [1, 2, 3].some(num => num > 1);console.log(trueOrFalse);

When we call some on array [1, 2, 3], each element is passed once to its callback num => num > 3 as an argument, represented by the parameter num.

In the first iteration, our callback look like this:

1 => 1 > 1

When 1 is passed as an argument, we get a return value of false, so we move to the next iteration.

2 => 2 > 1

When 2 is passed as an argument though, we get a return value of true.

Note that this is only the first return value we need to consider. The second return value to consider is the return value of the method call to some.

In short, we are saying that some uses the return value of its callback to determine its own return value.

In the example above, when the callback returns a truthy value, some then returns true.

Lets take a look at some more examples to help us understand some:

Example 1: ‘hi’

let firstValue = [1, 2, 3].some(num => 'hi');console.log(firstValue);
true

Example 2: num + 1

let firstValue = [1, 2, 3].some(num => num + 1);console.log(firstValue);
true

Notice that in both examples, the callbacks num => ‘hi’ & num => num + 1 evaluate to true for any value of num. We only care for the first value though, therefore, on the first iteration, some will return true and end execution.

Example 3: num — 1

let findTruthy = [1, 2, 3].some(num => num - 1);console.log(findTruthy);
true

In this example, when the value of num is 1 on the first iteration, the callback returns a falsy value (Number Literal 0)and we move to the next iteration until we find a truthy value.

In the next iteration, when the value of num is 2, we finally get a truthy value (Number Literal 1), where some returns true and ends execution. Note that this value is initialized to variable findTruthy.

Example 4: [1, 1, 1]

let noTruthy = [1, 1, 1].some(num => num - 1);console.log(noTruthy);
false

In this case, some will return false because there are no array values in [1, 1, 1] that when used as an argument to the callback num => num — 1 will return true. So to the noTruthy variable, we initialize with a value of false.

Example 5: some with strings

let str = “I’ll be back”;
let stringToArray = str.split(‘’);
str = stringToArray.some(char => char === ‘k’)
console.log(stringToArray);
// Logs [ ‘I’, “‘“, ‘l’, ‘l’,’ ‘, ‘b’, ‘e’, ‘ ‘, ‘b’, ‘a’, ‘c’, ‘k’]
console.log(str); // true

Notice the use of .split() that will allow us to use some.

Example 6: some with Objects

let food = { a: 'corndog', b: 'hotdog', c: 'cat-dog' };
let charLength = Object.values(food).some(foodType => foodType.length < 3);
console.log(charLength);
// false
let charLength2 = Object.values(food).some(foodType => foodType.length > 3);
console.log(charLength2);
// true

Notice the use of Object.values() that will allow us to use some.

In our example, the value charLength is false while the value of charLength2 is true. The difference lies in the Relational Operators < and >. Take a closer look!

Conclusion

After all is said and done, we now have a solid understanding of map, find and some. We know that all three methods - on each iteration - pass its array elements as arguments to its callback.

We know that map returns a new array based on the return values of its callback. We know that find returns the first element of its array ; where its callback returns a truthy value. And finally, we also know that some determines the boolean to return, based on the truthiness of its callback.

There was a ton to cover and it was exhilarating to cover.

Hopefully, those reading will have a better understanding of the topic and will be able to move forward more confidently like I will after spending a ton of time writing on it.

I hope my take was helpful, detailed and concise, and I look get better at writing such blogs, and get better at understanding JavaScript in general.

Thank you for reading!

--

--