Array Methods
Tags: javascript, react, beginners, tutorial
Published: 2021-04-28 22:08:56

# Introduction

Let's discuss a few common JavaScript array methods seen regularly in React.

But first, who is this post for? If you are new to JavaScript and/or React, and maybe unsure what you need to know to get started. This post is Part II in a series called Essential JavaScript Building Blocks for React, and we will take a look at several array methods, what they do, and how we use them in React.

JavaScript has A LOT of array methods. This [handy article](https://medium.com/@mandeepkaur1/a-list-of-javascript-array-methods-145d09dd19a0) by Mandeep Kaur briefly describes 20 different array methods.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lq9zjpxae0nmzs4v717m.jpeg)

This post, however, covers four array methods in more detail:
* .map()
* .filter()
* .find()
* .reduce()

And will reference a CodeSandbox that I created specifically for this series, with working examples of each array method.

{% codesandbox fruits-array-methods-9ycxn %}

## .map()

Others may disagree, but I use the map() array method more frequently than any other. What does map() do? According to the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map):

>The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

Ugh. If you are anything like me, "doc language" isn't the easiest to understand, especially when you're a newbie. 

According to me:

>map() takes an existing array, does something to each item in that array, and returns an entirely new array of the EXACT SAME LENGTH, a key attribute of map(). 

Let's perform a `map()` on this `coolArray`.

```javascript 
const coolArray = [1, 2, 3, 4, 5]

const newerCoolerArray = coolArray.map((number) => number * 100)

console.log(newerCoolerArray)
> [100, 200, 300, 400, 500]

console.log(coolArray)
> [1, 2, 3, 4, 5]
```
Notice that when you `console.log(coolArray)` it still holds the original values `[1, 2, 3, 4, 5]`.

It's important to reiterate that map() always returns a new array of the exact same length as the original.

```javascript
coolArray.length === newerCoolerArray.length
> true
```

## .map() in React

So how does map() pertain to React? A common pattern you will see with React is "mapping" data to various HTML elements, in order to display information to the user.

Let's check out that [CodeSandbox](https://codesandbox.io/s/fruits-array-methods-9ycxn?file=/src/App.js)! In `App.js` I created an array called `fruits`:

```javascript
const fruits = [
  "red apple 🍎",
  "green apple 🍏",
  "orange 🍊",
  "strawberry 🍓",
  "kiwi 🥝",
  "banana 🍌",
  "pineapple 🍍",
  "peach 🍑",
  "watermelon 🍉",
  "mango 🥭",
  "pear 🍐",
  "grapes 🍇",
  "cherries 🍒",
  "lemon 🍋",
  "melon 🍈",
  "coconut 🥥"
];
```
Which I pass down to my array method components, including `Map.js`.

```javascript
export default function Map(props) {
  return (
    <>
      <p className="method-header">
        The FRUITS array has been mapped to paragraph tags below
      </p>
      <p className="method-description">
        The .map method iterates over each item in the "fruits" array and applies the same function/logic to each item. Here we are creating a new paragraph with the p tag for each fruit in our array.
      </p>
      <div className="list-card">
        {props.fruits.map((fruit) => (
          <p key={fruit}>{fruit}</p>
        ))}
      </div>
    </>
  );
}
```

The key part of this component is:
```javascript
<div className="list-card">
  {props.fruits.map((fruit) => (
    <p key={fruit}>{fruit}</p>
  ))}
</div>
```

Let's break it down: inside a `<div>` we grab the `fruits` array passed down as props from `App.js`, and perform our map() to iterate over each `fruit` in the array, creating a new `<p>` for each item. Remember that map() accepts a function that it applies to each item in the array. In this case the function is simply us returning a `<p>` tag. 

If you navigate to the [CodeSandbox link](https://9ycxn.csb.app/) and select the ".map()" button, you will see our `<div className="list-card">` populated with a new line for each fruit! Cool, huh?

With map() you can easily render similarly grouped data to your user. If the array updates somewhere else, it will update in your component! Mapping gives you a handy way to display information without having to manually add a new HTML element for each entry.

## .filter()

What if you want to display specific items in your array, and not the whole kit and caboodle?

Enter the filter() method, a very powerful JavaScript function that you will see quite a lot. 

From the MDN Web Docs (yayyyy):

> The filter() method creates a new array with all elements that pass the test implemented by the provided function.

And my definition:

> filter() operates on an existing array, evaluates each item in the array, and whichever items meet the criteria that you define, adds those items to a new array. 

Welcome back, `coolArray`!

```javascript 
const coolArray = [1, 2, 3, 4, 5]

const filteredCoolArray = coolArray.filter((number) => number > 3)

console.log(filteredCoolArray)
> [4, 5]

console.log(coolArray)
> [1, 2, 3, 4, 5]
```

So what is happening here? filter() takes a function `(number) => number > 3` and uses that function to check against each item (number) in the array. Our function asks is the current item in the array greater than 3?

If you were to `console.log` inside the filter() you would see that each item is being evaluated to `true` or `false`. Any item that evaluates to `true` is added to the new array.

```javascript 
coolArray.filter((number) => console.log(number > 3))

> false // 1 is not greater than 3
> false // 2 is not greater than 3
> false // 3 is not greater than 3
> true // 4 is greater than 4
> true // 5 is greater than 4
```

And it's pretty obvious here, but we still want to highlight that the main difference between map() and filter() is that almost always filter() returns a new, SHORTER array than the orginal.

```javascript
coolArray.length
> 5

filteredCoolArray.length
> 2

coolArray.length === filteredCoolArray.length
> false
```

## .filter() in React

Take a look at [Filter.js](https://codesandbox.io/s/fruits-array-methods-9ycxn?file=/src/Filter.js). There is a lot going on here, especially if you're new to React. But let's focus on line 20:

```javascript
const filteredByLength = props.fruits.filter((fruit) => fruit.length > 10);
```

Inside `props.fruits.filter()` we pass the function `(fruit) => fruit.length > 10` which asks, "Is the current fruit greater than 10 characters long?" 

```javascript
console.log(filteredByLength)
> ["red apple 🍎", "green apple 🍏", "strawberry 🍓", "pineapple 🍍", "watermelon 🍉", "cherries 🍒"]

filteredByLength.length
> 6 // six fruits evaluate to "true" and make it into the new array
```

From there we can use our favorite map() method on the `filteredByLength` array to render only the 6 fruits that are longer than 10 characters:

```javascript
<div className="list-card">
  {filteredByLength.map((fruit) => (
    <p key={fruit}>{fruit}</p>
  ))}
</div>
```
Next I demonstrate how to combine filter() and includes().

**Bonus content!** 

Let's briefly talk about includes().

From the [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes):

> The includes() method determines whether an array includes a certain value among its entries, returning `true` or `false` as appropriate.

```javascript
const coolArray = [1, 2, 3, 4, 5]

console.log(coolArray.includes(3))
> true

console.log(coolArray.includes(6))
> false

```

If **any** item in a given array satisfies the condition, the return value is `true`. If no item in the array satisfies the condition, the return value is `false`.

When you inject this functionality inside of a filter(), each iteration of the filter() method will check against each single item. 

If the return from the includes() is `true` inside a filter(), that specific item is added to the new array generated by filter().

Take a look at this smaller `fruits` array. The filter() method iterates through the array, checking to see if each item in the array includes() a `"w"`.  We can see that 2 items contain a `"w"`.

```javascript
 
fruits = ["apple", "pear", "kiwi", "watermelon"]

fruits.filter(fruit => fruit.includes("w"))

> (2) ["kiwi", "watermelon"]

```
**Back to our regularly scheduled programming** 

Take a look at how I use filter() and includes() in my Codesandbox to find only fruits with the word `"apple"` in them.

```javascript
const appleFilter = props.fruits.filter((fruit) => fruit.includes("apple"));
```

Which gives us three fruits: 
```javascript
red apple 🍎
green apple 🍏
pineapple 🍍
```

And map() to `<p>` tags like the `filteredByLength` array:

```javascript
<div className="list-card">
  {appleFilter.map((fruit) => (
    <p key={fruit}>{fruit}</p>
  ))}
</div>
```

Lastly, I wired up a simple form that stores a user's input in local state, `query`. A function `findFruit()` is called on submit:

```javascript
  const findFruit = (e) => {
    e.preventDefault();
    if (query === "") {
      setFilteredFruits([]);
    } else {
      setFilteredFruits(props.fruits.filter((fruit) => fruit.includes(query)));
    }
  };
```
Now you can see in [real time](https://9ycxn.csb.app/) that when you select the filter() tab, there is an input at the bottom. Type in a character or two and hit submit. This is essentially how a search function works!

## .find()

Sometimes when you are working with an array, you want only one matching item. 

From [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)

> The find() method returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.

And my defintion:

> find() searches through an existing array, checking each item in the array against a function that you provide, and the FIRST item that returns `true` is returned. At this point find() stops checking for any more matches.

Let's view an example with `coolArray`.

```javascript
const coolArray = [1, 2, 3, 4, 5]

const greaterThanTwo = coolArray.find(number => number > 2)

console.log(greaterThanTwo)
> 3
```
`3` is the first item in the array that satisfies the logic `number => number > 2`.

And confirming that find() returns the first item that satisfies `true`

```javascript
coolArray.find((number) => console.log(number > 2))

> false // 1 is not greater than 2
> false // 2 is not greater than 2
> true // 3 is greater than 2 <-- RETURNED
> true // 4 is greater than 2
> true // 5 is greater than 2
```

## .find() in React

When working with React, you often render specific data based on specific needs/requirements. Like we saw with filter(), we rendered `<p>` tags of fruits that met a certain requirement.

Similarly, you may want to show only the first matching item from an array. 

In the Codesandbox, under the ".find()" tab, I copy/paste the input form and functions from `Filter.js` into `Find.js` and change the filter() method to find().

Now when a user types in a single character, a few, or the entire matching phrase, only one fruit will ever be returned. The first match will always be whatever comes first in the array. 

```javascript 
const fruits = [
  "red apple 🍎",
  "green apple 🍏",
  "orange 🍊",
  "strawberry 🍓",
  "kiwi 🥝",
  "banana 🍌",
  "pineapple 🍍",
  "peach 🍑",
  "watermelon 🍉",
  "mango 🥭",
  "pear 🍐",
  "grapes 🍇",
  "cherries 🍒",
  "lemon 🍋",
  "melon 🍈",
  "coconut 🥥"
];

const findAFruit = fruits.find((fruit) => fruit === "apple")

console.log(findAFruit)
> "red apple 🍎"
```

Even though three of our fruits contain the characters "apple", `"red apple 🍎"` is the first matching item in our `fruits` array.

## mental break time 

![Relaxing gif of ocean waves under a pier at sunset](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdyg5jljrn663tadye3a.gif)

Let's take a moment to enjoy this relaxing gif of a sunset over an ocean pier. We're about to take a look at our final array method, `.reduce()` and it's a doozy. Take as long as you need. When you are feeling thoroughly relaxed, we'll dive in...

## .reduce()

The reduce() method is incredibly powerful, but can be intimidating to beginners. I am STILL intimidated sometimes! The most important thing to remember about reduce() is it operates on every single item in an array, and returns a single value. In other words, it takes all the items in your array and REDUCES them down to one single item. reduce() gives you a lot of control on how you can do achieve the desired end result.

From the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce):

> The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.

Check out this example with `coolArray` to reduce all the numbers to a single value:

```javascript 
const coolArray = [1, 2, 3, 4, 5]

const reduceCoolArray = coolArray.reduce((accumulator, currentValue) => {
  return accumulator + currentValue
}, 0)

console.log(reduceCoolArray)
> 15

// Each argument's current value as it steps through the array:
// Pass 1. accumulator = 0, currentValue = 1, return value = 1. 
// Pass 2. accumulator = 1, currentValue = 2, return value = 3. 
// Pass 3. accumulator = 3, currentValue = 3, return value = 6.
// Pass 4. accumulator = 6, currentValue = 4, return value = 10.
// Pass 5. accumulator = 10, currentValue = 5 final return value = 15.
```
Whew. A lot to unpack here. According to the MDN docs:

> The reducer function takes four arguments
1. Accumulator
2. Current Value
3. Current Index
4. Source Array

> Your reducer function's returned value is assigned to the accumulator, whose value is remembered across each iteration throughout the array, and ultimately becomes the final, single resulting value.

For now, we will just focus on the Accumulator and Current Value arguments.

Let's break down the above code snippet:

The `0` at the end of the provided function is the initial value at which the accumulator begins. If we change the `initialValue` to something else, the accumulator begins at that value and we will receive a different final output value.

(If there is no `initialValue`, the accumulator initializes as the first item in the array).

```javascript 
const coolArray = [1, 2, 3, 4, 5]

const startAt100 = coolArray.reduce((accumulator, currentValue) => {
  return accumulator + currentValue
}, 100)

console.log(startAt100)
> 115

// The value of each argument during the iteration process:
// Pass 1. accumulator = 100, currentValue = 1, return value = 101. 
// Pass 2. accumulator = 101, currentValue = 2, return value = 103. 
// Pass 3. accumulator = 103, currentValue = 3, return value = 106.
// Pass 4. accumulator = 106, currentValue = 4, return value = 110.
// Pass 5. accumulator = 110, currentValue = 5 final return value = 115.
```

Notice that the return value from the previous iteration/call becomes the new `accumulator` value.

## .reduce() in React

Okay, time to be honest with y'all. I had a difficult time thinking of a good use case for the reduce() method on our `fruits` array. 

Thankfully my friend [Katherine Peterson](https://twitter.com/katherinecodes) gave me the idea to transform the array of fruits into a single object with the fruit name as the `key` and its corresponding emoji as the `value`. 

Kind of like this `cuteAnimals` object:
```javascript
cuteAnimals = {
  hedgehog: "🦔",
  chipmunk: "🐿️",
  hamster: "🐹",
}
```

Navigate to the [Reduce.js](https://codesandbox.io/s/fruits-array-methods-9ycxn?file=/src/Reduce.js) file and look at lines `6-12`.

```javascript 
const fruitsObj = props.fruits.reduce((accumulator, currentValue) => {
  const fruitName = currentValue.slice(0, -3);
  const fruitEmoji = currentValue.slice(-2);
  const obj = { ...accumulator };
  obj[fruitName] = fruitEmoji;
  return obj;
}, {});
```

Notice the `initialValue` is set to an object, `{}`. If you recall, reduce() returns a single value. While an object can contain an infinite amount of information, it is still considered a single object/value.

Let's break it down:

```javascript
// remove the emoji, keeping only the fruit name
const fruitName = currentValue.slice(0, -3);
```
```javascript
// similarly, remove the fruit name, keeping only the emoji
const fruitEmoji = currentValue.slice(-2);
```
```javascript
// create an object that updates with each pass of the accumulator
const obj = { ...accumulator };
```
```javascript
// set the object's key to fruitName and value to fruitEmoji
obj[fruitName] = fruitEmoji;
```
```javascript
// finally return the obj
return obj;
```

Now we can `console.log` our `fruitsObj` object.

```console
> {red apple: "🍎", green apple: "🍏", orange: "🍊", strawberry: "🍓", kiwi: "🥝"…}
red apple: "🍎"
green apple: "🍏"
orange: "🍊"
strawberry: "🍓"
kiwi: "🥝"
banana: "🍌"
pineapple: "🍍"
peach: "🍑"
watermelon: "🍉"
mango: "🥭"
pear: "🍐"
grapes: "🍇"
cherries: "🍒"
lemon: "🍋"
melon: "🍈"
coconut: "🥥"
```

Woohoo! A single object with fruit names as the properties/keys and their corresponding emojis as the value!

In React you can't just render an object, or you get: 
```css
Error
Objects are not valid as a React child 
```
So you have to get fancy with Object.entries() and map().

```javascript
{`fruitsObj = {`}
{Object.entries(fruitsObj).map(([key, val]) => (
  <p key={key}>
    {key}: "{val}",
  </p>
))}
{`}`}
```
Giving us:

![Screen shot of fruitsObj object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xahzlip05fs7bgld9sed.jpg)

Cool! But, not very useful on its own.

What if we used `fruitsObj` to create a "search for emoji" feature? We can search by name, and if there are any matches, we get the corresponding emoji. 

I use the same form from both the filter() and find() sections to grab the user's input, `query`.

I decided to show the keys and values separated by columns in a table. 

Check it out:

```javascript 
<table className="table-card">
  <tbody>
    <tr>
      <th>FRUIT</th>
      <th>EMOJI</th>
    </tr>
    {query && atLeastOneTrueQuery ? (
      Object.entries(fruitsObj).map(([key, val]) =>
        key.includes(query) ? (
          <tr key={key + val}>
            <td key={key}>{key}</td>
            <td key={val}>{val}</td>
          </tr>
        ) : null
      )
    ) : (
      <tr>
        <td>No</td>
        <td>Matches</td>
      </tr>
    )}
  </tbody>
</table>
```

(I know, I know! Nested ternaries! 😱😱😱 Not the prettiest, or easiest to read. If you have a better idea how to refactor this, let me know! But it does the job for now.)

Essentially, if the user has typed in the search bar, `query` updates with the user's input. If `atLeastOneTrueQuery` holds at least one matching fruit, then map() and render the fruit(s) and its emoji in the table. Otherwise, render a table section that tells the user "No Matches".

Type in `"g"` and you can see four fruits contain the letter "g" and now we can grab their matching emojis!

![Screenshot of search function on fruits array reduced to single object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0hmpu03pvn6pi0cqnoza.jpg)

Hopefully this contrived example shows you how useful reduce() can be. There are probably a million better use cases for it. Let me know in the comments below if you've ever worked with reduce() and if you've done anything interesting with it!

## Wrapping Up

If you've made it this far, GREAT JOB. And thank you! My hope is you now better understand the array methods we covered, and how you can use them in React.

I learned so much creating these examples and writing this post. The reduce() method was the hardest for me to wrap my brain around, but I feel as though I have a much better understanding when and why to use it, and how it works.

If you enjoyed this article, please like it, save it, share it! Whatever you want to do with it! 

Also, follow me on [Twitter](https://twitter.com/memrook), where I talk about my development journey, share anything I am working on,  highlight other developers and their projects, and sometimes tweet silly memes!

When Part III in the Essential JavaScript Building Blocks for React series is released, come back and check that out!

I welcome your feedback, insight, criticism, ideas, etc! Let me know in the comments what you think!

Thank you again and BE GOOD!