Manipulate JavaScript Arrays the Functional Way
Tags: javascript, webdev, programming, beginners
Published: 2021-01-23 20:05:18

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Functional programming is a programming paradigm which states that we create computations as the evaluation of functions and avoid changing state and mutable data.

To write programs in a functional way, we use pure functions and immutable data structures.

In JavaScript, we can easily apply functional principles to arrays by using its built-in array methods.

In this article, we’ll look at the array methods that let us manipulate them in a functional way.

Filtering Items
===============

We can use the `filter` method to return an array with entries from the original array that has the condition that the callback of the `filter` method returns.

For example, if we have the following array:

```
const store = [{  
    name: "Apple",  
    price: 1  
  },  
  {  
    name: "Banana",  
    price: 2  
  },  
  {  
    name: "Grape",  
    price: 1.2  
  }  
];
```

We can get the items that have `price` less than 2 as follows:

```
const cheapItems = store.filter(s => s.price < 2);
```

Then we get the following for `cheapItems`:

```
[  
  {  
    "name": "Apple",  
    "price": 1  
  },  
  {  
    "name": "Grape",  
    "price": 1.2  
  }  
]
```

Using the `filter` method fits with the functional paradigm since the function is pure, given the same array and same condition, we always get the same results returned.

It also doesn’t change the existing elements of the array that it’s called on, which means we can’t accidentally change anything from the original array.

Mapping Array Objects
=====================

`map` is used to map entries of an array into something else. It’s frequently used to convert and transform data. Using `map` fits with the functional programming paradigm because again it’s a pure function that gives the same outputs for the given inputs, and it doesn’t change the original array.

As long as the function we pass into the `map` function to combine the values is pure, the `map` method should also be pure since it just calls this callback function and returns the updated values into a new array.

For example, given the following array:

```
const volumesInLiters = [{  
    name: "Milk",  
    volumeInLiters: 1  
  },  
  {  
    name: "Apple Juice",  
    volumeInLiters: 2  
  },  
  {  
    name: "Orange Joice",  
    volumeInLiters: 1.2  
  }  
];
```

We can add the `volumeInQuarts` field to each entry of the object and set the volume in quarts to as the value of each by writing:

```
const volumesInQuarts = volumesInLiters.map(v => {  
  v = {  
    ...v,  
    volumeInQuarts: v.volumeInLiters * 1.057  
  };  
  return v;  
})
```

We convert `v.volumeInLiters * 1.057` and set it to `volumeInQuarts` for each entry.

Then we get:

```
[  
  {  
    "name": "Milk",  
    "volumeInLiters": 1,  
    "volumeInQuarts": 1.057  
  },  
  {  
    "name": "Apple Juice",  
    "volumeInLiters": 2,  
    "volumeInQuarts": 2.114  
  },  
  {  
    "name": "Orange Joice",  
    "volumeInLiters": 1.2,  
    "volumeInQuarts": 1.2684  
  }  
]
```

Using Reduce to Combine Values of Array Entries
===============================================

Like `filter` and `map`, `reduce` also fits with the functional paradigm since we use it to gather entries of an array and return one value by the way that we specify.

As long as the function we pass into the `reduce` function to combine the values is pure, the `reduce` method should be pure. The function just calls the callback function we pass into `reduce` to compute the combined value.

For example, given the following array:

```
const store = [{  
    name: "Apple",  
    price: 1  
  },  
  {  
    name: "Banana",  
    price: 2  
  },  
  {  
    name: "Grape",  
    price: 1.2  
  }  
];
```

We can write the following to get the total price of all items:

```
const totalPrice = store.map(s => s.price).reduce((subtotal, b) => subtotal + b, 0);
```

We have to use `map` to map all the entries in the `store` array to price numbers. Then we can use the `reduce` method to add the new value to `subtotal`.

Then we should get `4.2` for `totalPrice`, which is the total of all the prices of the 3 items in `store`.

The second argument of `reduce` is the starting value of the reduction, or combining the values into one.

Conclusion
==========

The `filter`, `map`, and `reduce` array methods are the main methods for manipulating arrays in a functional manner. They all return values and don’t change the array that it’s called on. This makes it difficult to unintentionally change the values.

`filter` returns an array that meets the condition that we return in the callback that we pass in.

`map` returns a new array that has the values of the original array mapped to new values in a way that we specify.

`reduce` combines the values of array entries into one by taking a callback function that we pass in to do the combining and returns the combined value.

The functions are pure if we pass in pure functions to them as callbacks since they just call the functions that we pass in to do the manipulation.