The method
map()
creates a new array with the values that get returned by calling the function provided tomap(anyFunctionHere)
on every element of an array.
The array, on which the map()
is being executed is named as calling array.
Task
Given an array with reversed first names, create a new array with the same position of names in the original array but re-reversed(should make sense) first names.
Let's take a look how we could tackle it using for-loop
.
const arrayOfNames = ['anhsirK', 'nosaJ', 'nolE', 'drawdE'];
let arrayOfReversedNames = []; // declaring an empty array to store results.
for (let nameIndex = 0; nameIndex < arrayOfNames.length; nameIndex = nameIndex + 1) {
// we can reverse a string in JavaScript with String.split("").reverse().join("")
const reversedFirstName = arrayOfNames[nameIndex].split('').reverse().join('');
arrayOfReversedNames.push(reversedFirstName);
}
// output: [ 'Krishna', 'Jason', 'Elon', 'Edward' ]
In the above example, we declared arrayOfReversedNames
and then appended calculated reverse names to that array.
It's time to solve the same problem, but with the use of map()
method.
const arrayOfNames = ['anhsirK', 'nosaJ', 'nolE', 'drawdE'];
// declaring an empty array to store results.
let arrayOfReversedNames = arrayOfNames.map((firstName) => {
return firstName.split("").reverse().join("")
});
// arrayOfReversedNames: [ 'Krishna', 'Jason', 'Elon', 'Edward' ]
We pass in an arrow function to map()
with an argument firstName
. firstName
will have a different value in each iteration on the elements of the calling array. Here in the first iteration, the value of firstName
would be anhsirK
, nosaJ
in the second iteration, and so on... It's clear that we get the same results because map()
is also doing the same iteration that for-loop
was doing.
At this point you might ask if both methods are doing the same thing that is iteration over elements of the calling array, shouldn't we use for-loop
instead of map()
? It's more readable and explicitly describes what is being done there.
Well, yes and no.
Benefits of using map()
over for-loop
- Fewer lines of code - mostly better!
- We get access to individual elements of the calling array directly with an argument in the function passed on to
map()
- far easier than always getting values withcallingArray[someIndex]
. - A certainty that all elements of the array will be iterated with
map()
- never deal with wrong indices inside afor-loop
anymore.
All we know at the end of the day is that when we have an array and we want to process every element of that array and store values in a new one, map()
is the way to go.
This is originally written at my blog
Edit:
Take a look at the comment on this post made by Brett Thurston to get more info on where not to use map()
as per MDN.
Top comments (13)
I'm not sure I see the value here, provided it's just syntactical difference (it's not, see the other comments). If it were just a matter of syntactical sugar, this whole post could have been addressed by bringing the Array.forEach() to Author's attention, which in the simpler terms, is an "Array.map()"-like syntax for for-loop.
i.e.
The main benefit of taking
thisArray
as the last argument to lambda is the fact that you can encapsulate the behaviour in a named function (here a lambda is provided). Rest is pretty obvious.In the task I mentioned above for reversing strings and putting them in a new array, I agree that
forEach
is a good approach.I personally would still prefer
map()
overforEach()
becausenewArray
manuallymap()
returns an array. we can do further processing on array like filtering and sorting right there after runningmap()
without ever need to manipulatenewArray
.For example.
totally agree!
It's not a bad approach, but MAP should be used for simple events, most of the time when you loop through an array you're going to be doing a lot more than just one thing. In those cases, use a for loop if you don't want to hate yourself six months later.
Also your naming convention is what makes your for loop harder to read.
This is far simpler to understand, now, AND in six months versus the MAP method.
const names = ['anhsirK', 'nosaJ', 'nolE', 'drawdE'];
let reversednames = [];
for (let i = 0; i < names.length; i++) {
const reversedname = names[i].split('').reverse().join('');
reversednames.push(reversedname);
}
/Disclaimer/
I'm super anti-camelcase. Using lowercase names and keeping them short makes your code immediately easier to read, plus you will NEVER have a syntax bug because you typo'd an uppercase letter, so hours saved. You can use underscores if needed.
Was it not for the example above being descriptive i'd probably just go with
"revs" in place of "reversednames" and "rname" in place of "reversedname".
Just to simplify the code more.
Your variable names should not overtake the logic visibly.
I think there's a balance to be struck in terms of maintainability when naming variables. Sure, overly verbose variable names are clunky and can make things harder to read, but on the other hand
revs
andrname
a) gives me no context (isrevs
something about revolutions?) and b) can be easily misread (looks a quite similar tomame
).I think with IDEs, things like typos become far less of a problem, so I'd personally stay away from lots of abbreviations.
I also think that this specific task fits quite well with your suggestion of what
.map()
should be used with. It's short, single manipulation and, with proper naming and shorthand functions, is quite succinct:reversedNames = names.map(name => name.split('').reverse().join(''))
I also agree with you that with the modern age of IDEs and linters, typos have become far less of a problem unless we're doing something over ssh on a raspberry pi and have to use vim or nano. But if I am to do real programming on ssh, I would prefer using vscode remote containers mode and code there rather programming in vim / nano on over ssh.
Don't let the vim enthusiasts hear that! You'll be stuck for hours as they tell you the 9000 ways of making vim fully sentient and writing the code for you haha!
True to that. I've done that many times myself as I am a big VIM fan and even use VSCode vim mode today. I've used it as my main developing software for a year but the problem begun when I started working professionally as a fronend dev, other people were using .editorconfig and prettier and stuff which I found were a bit ( for me ) cumbersome to implement and therefore I switched to VSCode. Though my love for Vim and it's ways to handle things is eternal.
For smaller logics, having a
for-loop
is no problem at all, but as I mentioned here, we have logics were we're doing multiple processes on array like sorting/filtering/reducing to one value,map()
is imo better as we can do it in one place.Also array methods like
map()
andfilter()
andreduce()
are an integral part of todays frontend development as no backend gives us all the customization we want in the response and thus we always have to manipulate data in frontend and same as for-loop or forEach loop, these array methods are integral part of processing the data in frontend so a developer imo should be enough familiar with these methods to even understand code that he has not written. ( to be noted that I am not supporting bad code styles or anything here ).And libraries like Lodash came into existence for the need of finding and creating and manipulating data and with it's API where we can chain processing to be done on array, it makes our work a lots of easier than writing a for loop every time we want to execute certain processes on an array.
I just wrote a primer on the map method and in full disclosure, I've been using map as replacements for loops. MDN says, that shouldn't be used in that case and ONLY use it if you intended to use the array returned from the method.
dev.to/brettthurs10/grab-your-map-...
MDN bit:
developer.mozilla.org/en-US/docs/W...
dev-to-uploads.s3.amazonaws.com/i/...
Thanks for sharing Brett, I loved that example of user cards.
I've mentioned in the Task description mentioned in the post that we need to
create a new array
, so that should be no problem for usingmap()
. Even though I will mention your comment in my post so readers can have a better look at info you provided here.for ... of is handy when serialize await async.
Explicit iteration for (classical for)? I rarely need to use it.
Yess, ES6 has been a boon for us.