JavaScript Array .map() vs .forEach()
Tags: javascript, beginners, webdev, tutorial
Published: 2021-10-17 21:49:13

*originally published @ [CatStach.io](https://www.catstache.io/blog/array-map-foreach)*

When working with arrays of data, it can be a bit confusing when you should reach for `map` or `forEach`, so in this post I hope to help clear that up!  
> tldr: use `map` if you want to make transformations to the data, use `forEach` if you want to perform side effects.

Lets imagine we have an array of store items that we would like to work with:

```javascript
const storeItems = [
  { name: 'Sunglasses', price: 15.00, memberDiscount: true},
  { name: 'Flip flops', price: 50.00, memberDiscount: true},
  { name: 'Sunscreen', price: 5.99, memberDiscount: false}
];
```

## Mapping
Say we wanted to use this data, but we wanted to modify the items to have all their names uppercase:

```javascript
const uppercaseItems = storeItems.map(item => {
  return {...item, name: item.name.toUpperCase()};
});
/*
[
  { name: 'SUNGLASSES', price: 15.00, memberDiscount: true},
  { name: 'FLIP FLOPS', price: 50.00, memberDiscount: true},
  { name: 'SUNSCREEN', price: 5.99, memberDiscount: false}
]
*/
```
The above function will return a new array with modified names, and it WONT update the storeItems array so that will continue to hold the initial values. 

For another example, what if we wanted to modify the price based on if there is a member discount, and the person currently viewing the data is a member.  We could write the following function: 

```javascript

const applyMemberDiscounts = (items, isMember) => {
  return items.map(item => {
    if (!item.memberDiscount || !isMember) return item;

    const price = item.price - (item.price * 0.20);
    return {...item, price};
  });
};

const discounted = applyMemberDiscounts(storeItems, true);
/*
[
  { name: 'Sunglasses', price: 12.00, memberDiscount: true},
  { name: 'Flip flops', price: 40.00, memberDiscount: true},
  { name: 'Sunscreen', price: 5.99, memberDiscount: false}
]
*/
```

For a final example, I'll talk about how I use map when rendering React components.  If I had some component, `<StoreItem>` that took all the values and made them look pretty, I would display them by building all the components and storing them in a new array, then later in the JSX I can just pass the array as children.

```javascript
const comps = storeItems.map(item => <StoreItem {...item} />)

...

// In component return
return (
  <div>
    {comps}
  </div>
)
```

You can probably start to imagine how you would use this in your code now - basically if you want to **transform** your data, and keep a copy of the old data, use map!

## Using forEach
The cases where you would want to use forEach would fall under "side effect" scenarios.  I pretty much only use `forEach` where I don't care about the result of the function that is being applied to the array elements. If you have some logging function (or in the simplest example `console.log`), the result of applying that function to the value is generally uninteresting, so `forEach` works well:

```javascript
storeItems.forEach(item => console.log(`${item.name}: $${item.price}`));
```

Or, if you have some sort of action dispatching system where you dont care about the result of dispatching, you could take some array of actions and use `forEach` to dispatch them all.

```javascript
const actions = [firstAction, secondAction]
actions.forEach(action => dispatch(action));
```

If you find yourself writing code like

```javascript
storeItems.forEach(item => item.name = item.name.toUpperCase());
```

I would highly suggest you swap to using `map` instead.  While the above is code that will compile and work, it is transforming the original dataset, and that can cause bugs that are difficult to track down!

## Conclusion
Both `map` and `forEach` have their place when working with arrays of data.  If you are wanting to make transformation to the data, reach for `map`.  If you are looking to do effectful computations based on the data without modifying it, reach for `forEach`!

I hope this helped in identifying the right tool for the job at hand!