Six ES6 methods to level up your Array game

Time to level up our Array game! With the advent of ES6, JavaScript Arrays have added new functionality that will enhance our programs and streamline the way we write code. In this post I will highlight six ES6 Array methods, outlining the ways we may have solved problems in the past and illustrating how we can use these new functions to do it (better) now.

Basically this post is a JavaScript Array version of old and busted vs new hotness.

Let’s get it.


Table Of Contents

Array.of()

The Array.of() method creates a new Array instance and can be used similarly to the constructor form of Array(). However, Array.of() avoids the key Array() gotcha that occurs when we pass in a number. Let’s create.

const a1 = new Array();
console.log(a1);  //[]
const a2 = Array.of();
console.log(a2);  //[]

//the gotcha...
const b1 = new Array(5);
console.log(b1);  //[undefined,undefined,undefined,undefined]
//the newness...
const b2 = Array.of(5);
console.log(b2);  //[5]

const c1 = new Array(1,2,3,4,5);
console.log(c1);  //[1, 2, 3, 4, 5]
const c2 = Array.of(1,2,3,4,5);
console.log(c2);  //[1, 2, 3, 4, 5]

There are a couple cases where this may be useful, but generally I still recommended creating an array by using the array literal syntax we have become accustomed to:

const a = [1,2,3,4,5];

Array.from()

The Array.from() method creates a shallow copy of an Array. We may have accomplished this in the past by creating a shallowCopy() function as outlined below.

function shallowCopy (a) {
  var temp = [];
  a.forEach(function(value) {
    temp.push(value);
  });
  return temp;
};

const arr = [1,2,3,4,5];
const temp = shallowCopy(arr);
console.log(temp);  //[ 1, 2, 3, 4, 5 ]

However, we can simplify that now with Array.from():

const arr = [1,2,3,4,5];
const a = Array.from(arr);
console.log(a);     //[ 1, 2, 3, 4, 5 ]

A note about Array.from(): This method copies the values, not the reference. So, the two arrays are not equal, as opposed to assigning an array to another variable, which ensures they point to the same location in memory, for example:

const a = [1,2,3,4,5];
const b = Array.from(a);
const c = a;

console.log (b === a);  //false
console.log (a === c);  //true

For more on value vs reference, check out this post.

Array.prototype.fill()

The fill() method fills all (or part) of an array with a value from a start index up to (but not including) an end index. The first parameter is the value to fill the array, while the second parameter is the start index, which defaults to 0. The third parameter is the end index, which defaults to this.length.

const d = Array(5).fill(0);
console.log(d);          //[0,0,0,0,0]
const e = Array(5).fill(0,1,4);
console.log(e);          //[undefined, 0, 0, 0, undefined];

Please note that this method will not change the length of the array. So if you have an empty array, it will not add items:

const a = [];
console.log(a);             //[]
const b = a.fill(0, 1, 3);
console.log(a);             //[]
console.log(b);             //[]

const c = [1,2,3];
console.log(c.fill(0, 1));  //[1,0,0]

How might we use this function? Well, let’s envision the following scenario: What if you have a game board represented by an array and you wanted to (re)initialize each value in the array to -1 (basically “reseting” the game)?

var board = [];
var length = 5;
var initialValue = -1;

//Previously, we may have written a function like the following
//to set an initial value for every index in our array
function initializeBoard(board, length, initialValue) {
  for (var i = 0; i < length; i++) {
    board[i] = initialValue;
  }
}

initializeBoard(board, length, initialValue);
console.log(board);         //[ -1, -1, -1, -1, -1 ]

//new way of doing it
const newBoard = [];
newBoard.length = length;
newBoard.fill(-1);
console.log(newBoard);      //[ -1, -1, -1, -1, -1 ]

//or better yet...
const newBoard2 = Array(length).fill(-1);
console.log(newBoard2);     //[ -1, -1, -1, -1, -1 ]

Array.prototype.find()

The find() method takes a “matching” function and returns the first value that is true or undefined if no value is found.

const a = [5, 12, 8, 130, 44];

const found = a.find(function(element) {
  return element > 10;
});

console.log(found); //12

Cool…so how might we use this to improve our JS skills? Glad you asked, I got you. This code is a modified example from a server validation script I wrote, which checks that our AWS infrastructure has been properly built via Terraform. With the context covered, let’s get to the code.

const subnets = [
  {
    'name': 'subnet-a',
    'SubnetId': 1
  },
  {
    'name': 'subnet-b',
    'SubnetId': 2
  },
  {
    'name': 'subnet-c',
    'SubnetId': 3
  },
  {
    'name': 'subnet-d',
    'SubnetId': 4
  },
  {
    'name': 'subnet-e',
    'SubnetId': 5
  },  
];

//let's search the array of subnets
//to find a particular one given an ID
const getSubnetById = subnetId => {
  const numSubnets = subnets.length;
  for (let i=0; i < numSubnets; i++) {
    if (subnets[i]['SubnetId'] === subnetId) {
      return subnets[i];
    }
  }
}

console.log(getSubnetById(1));    //{ name: 'subnet-a', SubnetId: 1 }

//using the find method
const mySubnet = subnets.find(el => el['SubnetId'] === 1);
console.log(mySubnet);            //{ name: 'subnet-a', SubnetId: 1 }

//we could easily make this a reusable function
const findSubnetById = subnetId => subnets.find(el => el['SubnetId'] === subnetId);
console.log(findSubnetById(4));   //{ name: 'subnet-a', SubnetId: 4 }

As we can see, the find() method helped us reduce a lot of “boilerplate” code. These are for loops we have all written a minimum of 27,841,991 times and now we can (for the most part) stop writing them. Let’s keep leveling up!

Array.prototype.findIndex()

Say I wanted to find the index of the first value in an Array of numbers greater than 25, in ES5 (or earlier) I might’ve done something like this…

var arr = [10,20,30,40,50];
var value = 25;
var index;

function getIndex(array, value) {
  for (var i = 0; i < array.length; i++) {
    if (array[i] > value) {
      return i;
    }
  }
}

index = getIndex(arr, value);
console.log(index); //2

…but now ES6 is in the building! Enter findIndex(). This method takes a matching function and returns the index of the first element in the Array, which satisfies the condition.

const value = 25;
const indexWithNoWork = arr.findIndex(num => num > value);
console.log(indexWithNoWork); //2

Array.prototype.includes()

What if we want to determine whether a value exists in an Array? We can use the includes() method to do this.

var arr = [10,20,30,40,50];

//pre-ES6
function existsInArray(array, value) {
  //before we would use indexOf
  for (var i = 0; i < array.length; i++) {
    if (array.indexOf(value) !== -1) {
      return true;
    }
  }
  return false;
}

console.log(existsInArray(arr, 40));      //true
console.log(existsInArray(arr, 4));       //false
console.log(existsInArray(arr, 'hello')); //false

//that ES6 wave
console.log(arr.includes(40));            //true
console.log(arr.includes(4));             //false
console.log(arr.includes('hello'));       //false

Bonus: Array.prototype.filter()

No post on leveling up can dared be written without the almighty filter(). While not ES6 (originally introduced in ES5), this is a powerful method that can greatly improve code readability and efficiency. filter() takes a matching function and returns an array of all the elements that match the condition.

Let’s return the list of elements greater than 25, showing both pre and post ES5 implementations.

//pre-ES5
var arr = [10,20,30,40,50];
var value = 25;
var filteredArray;

function filter(array, value) {
  var temp = [];
  for (var i = 0; i < array.length; i++) {
    if (array[i] > value) {
      temp.push(array[i]);
    }
  }
  return temp;
}

filteredArray = filter(arr, value);
console.log(filteredArray); //[ 30, 40, 50 ]

//ES5 now and forever
const newArray = arr.filter(num => num > value);
console.log(newArray);      //[ 30, 40, 50 ]

For a more in depth example, check out this snippet on Github.

Conclusion

In this post we have shown that by utilizing these new Array methods we can simplify our programs, write less code that will reduce our cognitive load as we develop, and improve our JavaScript capabilities. Check out the additional resources below and happy coding!

Additional Resources

Updated: