ES6 - A beginners guide - Array Helpers
Tags: javascript, webdev, beginners, codenewbie
Published: 2022-01-23 12:52:47

You made it to the last post in the series, sorry it's delayed work priorities took precedence over writing this up. This time I will cover Array Helpers, now some of this were drafted into ES5.1 but finalised into code in ES6, so these have been known about for a little while before being public, and of course I am covering ES6 7 years after it was publicly released (always playing catchup in the dev world!). 
Arrays are pretty much common place in any JS application, so it makes sense we have some common functions that we can call to help process/manipulate/handle them. ES6 introduced 6 new helper functions, namely: 
- forEach
- map
- reduce
- filter
- find
- every
- and some 
and in this article I am going to look into these into a bit more detail and we'll take a look at some examples along the way :) 
## forEach()
The purpose of `forEach()` is a relatively simple, for each record in an array do something. So using our array, let's say we want to just output the objects into the DOM, we can use a function that does that, and use it as the parameter for `forEach()`.`forEach()` takes 2 parameters:
- `function`, this is our processing function which itself can contain 3 parameters, these are:
  - `currentValue` (required) - this is the current element
  - `index` (optional) - this is the index of the current element
  - `arr` (optional) - this is the array that the current element exists in
- `thisValue` (optional) - This is a value to be passed into our `function` as it's reference to `this`
Let's take a look at an example of `forEach()`:
``` javascript
var blogs = [
    { id: 10, title: 'Daily JS' },
    { id: 20, title: 'Code Refactor Daily' },
    { id: 30, title: 'The Brightest React-ion' }
];

const outputBlogs = (blog) => {
    document.body.innerHTML += `<p>${JSON.stringify(blog)}</p>`
};

blogs.forEach(outputBlogs)
```
This code will simply just output the following paragraph nodes at the end of the body element:
``` html
<p>{"id":10,"title":"Daily JS"}</p>
<p>{"id":20,"title":"Code Refactor Daily"}</p>
<p>{"id":30,"title":"The Brightest React-ion"}</p>
```
This is of course a very simple example, but very easily shows how we can walk through the array and perform a function on each entry. A more in-depth example would perhaps be an array of images, and we want to store the area these images would take up in another array. For example:
``` javascript
var images = [
  { height: 10, width: 30 },
  { height: 20, width: 90 },
  { height: 54, width: 32 }
];
var areas = [];

images.forEach(function(image){
  areas.push(image.height * image.width)
})
document.body.innerHTML += `<p>${JSON.stringify(areas)}</p>`
```
In this example we would have the array printed out into a paragraph node that reads `[300,1800,1728]`, so here what we have is a function that is being trigger on each array item, which takes 2 object properties, and then pushes them into another array which we then output.
## map()
In the above example, we could have worked this differently, we could have instead used the `map()` helper. Map essentially takes one array, iterates through it, processing it with another function, and appends the item to an array that `map()` created. `map()` takes 2 parameters:
- `function`, this is our map function which itself can contain 3 parameters, these are:
  - `currentValue` (required) - this is the current element
  - `index` (optional) - this is the index of the current element
  - `arr` (optional) - this is the array that the current element exists in
- `thisValue` (optional) - This is a value to be passed into our `function` as it's reference to `this`
Let's take a look at an example:
``` javascript
var blogs = [
    { id: 10, title: 'Daily JS' },
    { id: 20, title: 'Code Refactor Daily' },
    { id: 30, title: 'The Brightest React-ion' }
];

let blogTitles = blogs.map((blog) => blog.title)

document.body.innerHTML += `<p>${JSON.stringify(blogTitles)}</p>`
```
In the above example we will have an output that reads: `["Daily JS","Code Refactor Daily","The Brightest React-ion"]`.
There is one thing to always ensure you remember with `map()` and that is that you must ensure you return a value in your function else you will get an array of undefined values, the length will still be the same as the existing array but as your callback function doesn't return a value it cannot store anything.
 As mentioned above the function you call inside of `map()` can actually take 3 parameters, 2 of which are optional. We have already seen `currentValue` which was `blog`, we can also pass `index` which is the index position of the current element, and `arr` which outputs the array that contains the current element (I cannot find an actual useful implementation of this param, feel free to shout out with any example you might have found though). Let's take a look at our example above with the index added:
``` javascript
let blogTitles = blogs.map((blog, index) => `index: ${index} is ${blog.title}`)

document.body.innerHTML += `<p>${JSON.stringify(blogTitles)}</p>`
```
This updated example will now give us an output of `["index: 0 is Daily JS","index: 1 is Code Refactor Daily","index: 2 is The Brightest React-ion"]`. This functionality is a lot easy than using a traditional for loop where we would have to access something like `i` for each element in the loop.
## reduce() 
The `reduce()` filter is definitely an interesting filter, It will ingest the array elements, pass them through a "reducer function", and output an accumulated result. `reduce()` takes 2 parameters:
- `function`, this is our reducer function which itself can contain 4 parameters, these are:
  - `total` (required) - this is the initialValue OR thw previously returned value of the function
  - `currentValue` (required) - this is the current element
  - `currentIndex` (optional) - this is the index of the current element
  - `arr` (optional) - this is the array that the current element exists in
- `initialValue` (optional) - This is a value to be passed into our `function` as it's initial value
Let's look at an example:
``` javascript
var trips = [{ distance: 34 }, { distance: 12 } , { distance: 1 }];

var totalDistance = trips.reduce((sum, trip) => { return sum += trip.distance }, 0);
```
In our example above, we start our `totalDistance` variable with an `initialValue` of 0. Then we will traverse through our `trips` array, and then for each item in there we call our reducer function, this takes `sum` as the `total` parameter (which defaults to 0 in our `initialValue`), and `trip` as the `currentValue`. Our return from this function is our `sum`/`initialValue` + the `distance` property of the element we are currently on. If we run this in the browser is will tell us that `totalDistance` is 47.
We would also use the `reduce()` helper to aid us in counting the occurences of a string in an array. For example, let's say we have an inventory of IT equipment such as desks, we have a mix of sitting and standing style desks. Using the `reduce()` function we can easily count these easily:
``` javascript
var desks = [
    { type: 'sitting' },
    { type: 'standing' },
    { type: 'sitting' },
    { type: 'sitting' },
    { type: 'standing' }
  ];
  
var deskTypes = desks.reduce(function(retVal, desk) {
    retVal[desk.type] ++
    return retVal
}, { sitting: 0, standing: 0 });
```
In the output above, we would see `{sitting: 3, standing: 2}`, there is a slight shortfall in this example however if we wanted to count all the elements but they were not included in the `initialValue` we could get such as `{"sitting":3,"standing":1,"adjustable":null}`. There is a way to combat this, with the use to 2 seperate reducing functions, let's take a look:
``` javascript
function uniqueValues(array) {
  var reducedToObject = array.reduce(function (retVal, desk) {
    // If we have no retValue length, 
    // or if we cannot find desk element we add a new object property
    if (
      !retVal.length || !retVal.find(function (desks) {
        return desks == desk.type;
      })
    ) {
      // Add the unique property to our object with a default 0 value
      retVal[desk.type] = 0;
      return retVal;
    }
    return retVal;
  }, {});
  return reducedToObject;
}
var desks = [
  { type: 'sitting' },
  { type: 'standing' },
  { type: 'sitting' },
  { type: 'sitting' },
  { type: 'standing' },
  { type: 'sitting' },
  { type: 'standing' },
  { type: 'adjustable' },
  { type: 'adjustable' },
];

var deskTypeCount = desks.reduce(function(retVal, desk) {
    retVal[desk.type] ++
    return retVal
}, uniqueValues(desks));
```
In the above example we will now use a reducer `reducedToObject` to find the unique values in our array, we will then use that value in our `deskTypeCount` reducer function, ultimately this gives us `{"sitting":4,"standing":3,"adjustable":2}`. The `reduce()` helper, is super powerful in scenarios just like this!
## filter()
The `filter()` handler quickly allows us to take one array, and output it to another array pulling a subset of entries from the first, if nothin in the original array matches the filter then we will get an empty array. 
- `function`, this is our filter function which itself can contain 3 parameters, these are:
  - `currentValue` (required) - this is the current element
  - `index` (optional) - this is the index of the current element
  - `arr` (optional) - this is the array that the current element exists in
- `thisValue` (optional) - This is a value to be passed into our `function` as it's initial value
Let's look at an example:
``` javascript
var blogs = [
    { id: 10, title: 'Daily JS' },
    { id: 20, title: 'Code Refactor Daily' },
    { id: 30, title: 'The Brightest React-ion' }
];

var filteredBlogs = blogs.filter(user => {
  return blog.id > 10
})
```
In the above example `filteredBlogs` will be the following array `[{id: 20, title: "Code Refactor Daily"}, {id: 30, title: "The Brightest React-ion"}]`. We would also use filter utilise the index parameter for a subset of blog posts, perhaps for something like pagination and filtering. For example, lets say we want to filter for javascript blogs, and just look in a specific block of results. We could use date or similar, but to keep it simple we could do something like this just grouping in a range of index positions:
``` javascript
var blogs = [
	{blogPostId:100, title:"The best JS Guide", category:"Javascript"},
	{blogPostId:101, title:"Stefan's JS Guide", category:"Javascript"},
	{blogPostId:102, title:"Stefan's Java Guide", category:"Java"},
	{blogPostId:103, title:"Stefan's HTML Guide", category:"HTML"},
	{blogPostId:104, title:"Stefan's NodeJS Guide", category:"Javascript"},
	{blogPostId:105, title:"Phil's JS Guide", category:"Javascript"},
	{blogPostId:106, title:"Phil's Java Guide", category:"Java"},
	{blogPostId:107, title:"Phil's HTML Guide", category:"HTML"},
	{blogPostId:108, title:"Phil's NodeJS Guide", category:"Javascript"},
	{blogPostId:109, title:"Simon's JS Guide", category:"Javascript"},
	{blogPostId:110, title:"Simon's Java Guide", category:"Java"},
	{blogPostId:111, title:"Simon's HTML Guide", category:"HTML"},
	{blogPostId:112, title:"Simon's NodeJS Guide", category:"Javascript"},
	{blogPostId:113, title:"Charley's JS Guide", category:"Javascript"},
	{blogPostId:114, title:"Charley's Java Guide", category:"Java"},
	{blogPostId:115, title:"Charley's HTML Guide", category:"HTML"},
	{blogPostId:116, title:"Charley's NodeJS Guide", category:"Javascript"},
]

const filteredBlogs = (blogPosts,page, category) => {
	return blogPosts.filter((post,index) => {
  	return (index > (page-1) * 5 && index < page * 5 && post.category == category)
  })
}
```
With the example above, if we were to call `filteredBlogs(blogs,1,"Javascript")` we would get a result such as `[{ blogPostId: 101, category: "Javascript", title: "Stefan's JS Guide"}, { blogPostId: 104, category: "Javascript", title: "Stefan's NodeJS Guide"}]` because we wanted posts between index position 0 and 5 with a category of "Javascript"
## find()
The `find()` helper is usefuly for finding the first element that passes a test. `find()` takes 2 parameters:
- `function`, this is our finder function which itself can contain 3 parameters, these are:
  - `currentValue` (required) - this is the current element
  - `index` (optional) - this is the index of the current element
  - `arr` (optional) - this is the array that the current element exists in
- `thisValue` (optional) - This is a value to be passed into our `function` as it's reference to `this`
An example we could use is using find to find the first blog in our Javascript category from our example above, for example:
``` javascript
var blogs = [
	{blogPostId:100, title:"The best JS Guide", category:"Javascript"},
	{blogPostId:101, title:"Stefan's JS Guide", category:"Javascript"},
	{blogPostId:102, title:"Stefan's Java Guide", category:"Java"},
	{blogPostId:103, title:"Stefan's HTML Guide", category:"HTML"},
	{blogPostId:104, title:"Stefan's NodeJS Guide", category:"Javascript"},
	{blogPostId:105, title:"Phil's JS Guide", category:"Javascript"},
	{blogPostId:106, title:"Phil's Java Guide", category:"Java"},
	{blogPostId:107, title:"Phil's HTML Guide", category:"HTML"},
	{blogPostId:108, title:"Phil's NodeJS Guide", category:"Javascript"},
	{blogPostId:109, title:"Simon's JS Guide", category:"Javascript"},
	{blogPostId:110, title:"Simon's Java Guide", category:"Java"},
	{blogPostId:111, title:"Simon's HTML Guide", category:"HTML"},
	{blogPostId:112, title:"Simon's NodeJS Guide", category:"Javascript"},
	{blogPostId:113, title:"Charley's JS Guide", category:"Javascript"},
	{blogPostId:114, title:"Charley's Java Guide", category:"Java"},
	{blogPostId:115, title:"Charley's HTML Guide", category:"HTML"},
	{blogPostId:116, title:"Charley's NodeJS Guide", category:"Javascript"},
]

const findFirstJSBlog = blogs.find(blog => {return blog.category === "Javascript"})
```
In this example, we will see that `findFirstJSBlog` gives the return value of `{blogPostId: 100, category: "Javascript", title: "The best JS Guide"}`. If we wanted to find an element by index, we could run the following:
``` javascript
const findFirstJSBlog = blogs.find((blog, index) => {return index === 1})
```
This would then give us `{ blogPostId: 101, category: "Javascript", title: "Stefan's JS Guide"}`, a good use case here would be for a previous/next page button in a blog system, for example if your blogs array was for the blog posts, you could then do something like the following:
``` javascript
let currentBlogIndex = 1
const findBlogByIndex = (position) => {
  switch (position) {
    case 'prev':
      currentBlogIndex -=  -1     
      break;
    case 'next':
      currentBlogIndex += +1;
      break;
  }
  return blogs.find((blog, index) => {
      return index === currentBlogIndex
  })
}

const findCurrentJSBlog = findBlogByIndex('current')
const findPrevJSBlog = findBlogByIndex('prev')
const findNextJSBlog = findBlogByIndex('next')
```
The above code allows us to easily get the current, previous, and next blog posts, with the 3 variables at the end giving us `{ blogPostId: 101, category: "Javascript", title: "Stefan's JS Guide"}`, `{ blogPostId: 100, category: "Javascript", title: "The best JS Guide"}`, and `{ blogPostId: 102, category: "Javascript", title: "Stefan's Java Guide"}` 
## every() and some()
Finally, we hit the last 2 helpers, `every()` and `some()` are probably the most logical sounding helpers from the whole bunch. Simply put, they will check an array, and return a boolean value based on the conditions of either every element or some elements matching the function condition. You could use this for form validation to ensure all required fields are completed (if you aren't already relying on built in validation supplied by most browsers), maybe you want to check that a series of requests are completed, we'll keep our example simple however and let's look at an array of objects listing blog posts again:
``` javascript 
var blogs = [
	{blogPostId:100, title:"The best JS Guide", category:"Javascript", published: true},
	{blogPostId:101, title:"Stefan's JS Guide", category:"Javascript", published: true},
	{blogPostId:102, title:"Stefan's Java Guide", category:"Java", published: false},
	{blogPostId:103, title:"Stefan's HTML Guide", category:"HTML", published: true}
]

const everyBlogPublished = blogs.every((blog) => {return blog.published})
const someBlogsPublished = blogs.some((blog) => {return blog.published})
```
If we were to call the two consts above, `everyBlogPublished` would return `false` and `someBlogsPublished` would return `true`. Pretty neat huh? There are literally tonnes of examples and use cases for these helpers around online, I think that the above should help anyone get started, let me know if there are any other examples you've seen that you like.