JavaScript Array Operations with Examples

This article illustrates the operations of JavaScript Array. These examples include built-in APIs and some custom functions, such as groupBy, union, objectToArray, etc.

Note if fruits is not initialized in examples, it is:

let fruits = ['Apple', 'Banana'];

Basic operations

Create

let fruits = ['Apple', 'Banana'];
let length = fruits.length;
// 2

let fruits1 = [];
fruits1.push('Apple'); // ['Apple']
fruits1.push('Banada');// ['Apple', 'Banana'];

let fruits2 = new Array('Apple', 'Banana');

// Creates an array of 2 empty slots, not slots with actual undefined values
let fruit3 = new Array(2);
console.log(fruits3);
// Array [undefined, undefined]

Create an two-dimensional array

let board = [
    ['A0','A1','A2'],
    ['B0','B1','B2'],
    ['C0','C1','C2']
];

Set values

Set values directly

let fruits = ['Apple', 'Banana'];
fruits[1] = 'Blackberry';

If you set a value at a new indexed position which is not contained in the array. The length of the array will be updated accordingly.

let fruits = ['Apple', 'Banana'];
fruits[4] = 'Damson';
console.log(fruits); // ['Apple', 'Banana', undefined, undefined, 'Damson'];
console.log(furits.length); // 5
console.log(Object.keys(fruits));  // ['0', '1', '4']

**Fill values **

The fill() method fills (modifies) all the elements of an array from a start index (default zero) to an end
index (default array length) with a static value. It returns the modified array.

Syntax: fill(value[, start[, end]])

let array1 = [1, 2, 3, 4];

// fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// expected output: [1, 2, 0, 0]

// fill with 5 from position 1
console.log(array1.fill(5, 1));
// expected output: [1, 5, 5, 5]

console.log(array1.fill(6));
// expected output: [6, 6, 6, 6]

Access

length

console.log(fruits.length);

[] operator

Access an element through index

let first = fruits[0];
// Apple

let last = fruits[fruits.length - 1];
// Banana

Note: It is possible to quote the array indexes, such as fruits['0'], although it is not necessary. The 0 in fruits[0] is coerced into a string by the JavaScript engine through an implicit toString conversion.

Add, change

push() – Add to the end

// push() changes the length and returns the new length
let newLength = fruits.push('Coconut'); // ["Apple", "Banana", "Coconut"]
// 3

unshift() – Add to the front

// unshift() changes the length and returns the new length
let newLength = fruits.unshift('Avocado');// ["Avocado", "Apple", "Banana"];
// 3

[] operator – Add by setting a value at a new index position

let fruits = ['Apple', 'Banana'];
fruits[4] = 'Damson';
console.log(fruits); // ['Apple', 'Banana', undefined, undefined, 'Damson'];
console.log(furits.length); // 5
console.log(Object.keys(fruits));  // ['0', '1', '4']

When setting a property on a JavaScript array when the property is an valid array index and that index is outside the current bounds of the array, the engine will update the array’s length property accordingly.

splice() – Add value of a specific position

The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place. It returns an array containing the deleted elements.

let arrDeletedItems = arr.splice(start[, deleteCount[, item1[, item2[, ...]]]])
  • start

    The index at which to start changing the array.

  • deleteCount

    The number of elements in the array to remove from start.

  • item1, item2, ...

    The elements to add to the array, beginning from start. If you do not specify any elements, splice() will only remove elements from the array.

Example

let fruits = ['Apple', 'Banada', 'Coconut'];

// Remove 0 item from index of 1, and adding new item 'Blueberry'
let deletedItems = fruits.splice(1, 0, 'Blueberry'); // Add at index
// deletedItems: []
// fruits: ['Apple', 'Blueberry', Banada', 'Coconut']

Delete, remove

Delete from the end of an array

The pop() method removes the last element from an array and returns that element. This method changes the length of the array.

It returns undefined if the array is empty.

// pop() returns the removed element, it changes the length
// remove Banada from the end
let last = fruits.pop(); // ["Apple"];
// Banada

Delete from the front of an array

// shift() returns the removed element, it changes the length
// remove Apple from the front
let first = fruits.shift(); // ["Banana"];
// Apple

Delete elements from any position of an array

The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place. It can be used to remove elements from any position.

let fruits = ['Apple', 'Banada', 'Coconut', 'Durian'];

// Delete fruits[1] and fruits[2]
let removed = fruits.splice(1, 2); // fruits: ['Apple', 'Durian']
console.log(removed); // ['Banada', 'Coconut']

Loop

There are several ways to loop over an array. Use mapreducefilter functions first if they satisfy your needs, otherwise use below loop operations. Although these function are slower, they are easier to code、read , maintain and test. See for vs for each vs (map, reduce, filter, find) for details.

Use for loop

for (let i = 0; i < furits.length; ++i) {
    console.log(furits[i]);
}

Use forEach method

The forEach() method executes a provided callback function once for each array element.

// The parameters of index and array are optional
fruits.forEach(function(currenValue, index, array) {
    console.log(curentValue, index);
});
// "Apple" 0
// "Banada" 1

Note: It is not invoked for index properties that have been deleted or are uninitialized. For example:

“`javascript
const arraySparse = [1,3,,7];
let numCallbackRuns = 0;

arraySparse.forEach(function (element) {
console.log(element);
numCallbackRuns++;
});
console.log(arraySparse); // 3
“`

Formatted print

Use console.table

console.table displays tabular data as a table. This feature is available in Web Workers.

console.table(['Apple', 'Banada']);
console.table(board); // prints a two-demensional array

Write your own function

function printArrayElements(element, index, array) {
    console.log('a[' + index + '] = ' + element);
}

fruits.forEach(printArrayElements);
// a[0] = "Apple"
// a[1] = "Banada"

Other Operations

Copy

Copy to a new array

The slice(begin, end) method returns a shallow copy of a portion of an array into a new array object (end not included) . The original array will not be modified.

let fruits = ['Apple', 'Banada'];
let shallowCopy = fruits.slice(); // this is how to make a copy
// ["Apple", "Banada"]

Syntax: slice([begin[, end]]).

Copy elements to the same array

The copyWithin(target, start, end) method shallow copies part of an array to target location in the same array and returns it without modifying its length.

Syntax: copyWithin(target[, start[, end]]).

let array1 = ['a', 'b', 'c', 'd', 'e'];

// copy to index 0 the element at index 3
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array ["d", "b", "c", "d", "e"]

// copy to index 1 all elements from index 3 to the end
console.log(array1.copyWithin(1, 3));
// expected output: Array ["d", "d", "e", "d", "e"]

Filter

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

let fruits = ['Apple', 'Banana', 'Blueberry'];
let bfruits = fruits.filter(val => val.startsWith('B'));
// ['Banana', 'Blueberray']

Find

findIndex()

The findIndex() method returns the index of the first element in the array that satisfies the provided testing function.

Syntax

arr.findIndex(callback( element[, index[, array]] )[, thisArg])

Parameters

  • callback

    A function to execute on each value in the array until the function returns true, indicating that the satisfying element was found.

    It takes three arguments:

    • element

    The current element being processed in the array.

    • index Optional

    The index of the current element being processed in the array.

    • array Optional

    The array findIndex() was called upon.

  • thisArg Optional

    Optional object to use as this when executing callback.

Examples

let furits = ['Apple', 'Banana'];

function startsWithB(element) {
   return element.startsWith('B');
}

console.log(fruits.findIndex(startsWithB));
// expected output: 1

find()

The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

let array1 = [5, 12, 8, 130, 44];

let elemnent = array1.find(function(element) {
    return element > 10;
});

console.log(element);
// 12

indexOf()

Get index of an element

The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.

Syntax

arr.indexOf(searchElement[, fromIndex])

Parameters

  • searchElement

    Element to locate in the array.

  • fromIndex Optional

    The index to start the search at. If the index is greater than or equal to the array’s length, -1 is returned, which means the array will not be searched. If the provided index value is a negative number, it is taken as the offset from the end of the array. Note: if the provided index is negative, the array is still searched from front to back. If the provided index is 0, then the whole array will be searched. Default: 0 (entire array is searched).

indexOf() compares searchElement to elements of the Array using strict equality (the same method used by the === or triple-equals operator).

Examples

let array = [2, 9, 9];
array.indexOf(2);     // 0
array.indexOf(7);     // -1
array.indexOf(9, 2);  // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0

includes()

Check whether an array includes a certain value

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

Syntax: includes(valueToFind[, fromIndex])

let fruits = ['Apple', 'Banana'];
console.log(fruits.includes('Orange'));// false
console.log(fruits.includes('App'));// false

Note: When comparing strings and characters, includes() is case-sensitive.

Note: Technically speaking, includes() uses the sameValueZero algorithm to determine whether the given element is found.

Join

The join(sperator) method creates and returns a new string by concatenating all of the elements in an array (or an array-like object), separated by commas or a specified separator string

let fruits = ['Apple', 'Banada'];

console.log(fruits.join());
// expected output: "Apple,Banada"

console.log(elements.join('-'));
// expected output: "Apple-Banada"

let board = [
  ['A','B','C'],
  ['D','E','F'],
  ['G','H','I']
];
console.log(board.join('n'));
// Output:
/*
A,B,C
D,E,F
G,H,I
*/

Merge / Concat

The concat()method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

let array1 = ['a', 'b', 'c'];
let array2 = ['d', 'e', 'f'];

console.log(array1.concat(array2));
// Array ["a", "b", "c", "d", "e", "f"]

Sort

Reverse

The reverse() method reverses an array in place. The first array element becomes the last, and the last array element becomes the first.

let array1 = ['one', 'two', 'three'];
let reversed = array1.reverse();
console.log(array1); // Array ['three', 'two', 'one']
console.log(reversed); // Array ['three', 'two', 'one']

Check/Test

Every: Test whether all elements pass provided function

The every() method tests whether all elements in the array pass the test implemented by the provided function.

function isBelowThreshold(currentValue) {
    return currentValue < 40;
}

let array1 = [1, 30, 39, 29, 10, 13];
console.log(array1.every(isBelowThreshold));
// true

Note: This method returns true for any condition put on an empty array.

Some: Test whether at least some elements pass provided function

The some() method tests whether at least one element in the array passes the test implemented by the provided function.

let even = function(element) {
    // checks whether an element is even
    return element % 2 === 0;
};

let array = [1, 2, 3, 4, 5];
console.log(array.some(even));
// true

Note: This method returns false for any condition put on an empty array.

isArray

The Array.isArray() method determines whether the passed value is an Array.

Array.isArray([1, 2, 3]);  // true
Array.isArray({foo: 123}); // false
Array.isArray('foobar');   // false
Array.isArray(undefined);  // false

isArray vs instance of

When checking for Array instance, Array.isArray is preferred over instanceof because it works through iframes.

String to Array, Map to Array, Set to Array

(Array.from('foo'));
// ['f', 'o', 'o']

The Array.from() method creates a new, shallow-copied Array instance from an array-like or iterable object.

Array.from() lets you create Arrays from:

  • array-like objects (objects with a length property and indexed elements) or
  • iterable objects (objects where you can get its elements, such as Map and Set)
const set = new Set(['foo', 'bar', 'baz', 'foo']);
Array.from(set);
// ['foo', 'bar', 'baz']

Other loops: map vs reduce

map

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

Syntax:

let new_array = arr.map(function callback(currentValue[, index[, array]]) {
    // Return element for new_array
}[, thisArg]
  • currentValue, the current value in the array
  • index
  • array, the array itself
  • thisArg, Value to use as this when executing callback.

Examples:

[1, 4, 9].map((val) => {
  return val * 2;
});
// It creates a new array: [2, 8, 18]

reduce

The reduce() method executes a callback on each element of the array, resulting in a single output value.

Syntax:

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  • accumulator

    The accumulator accumulates the callback’s return values. It is the accumulated value previously returned in the last invocation of the callback, or initialValue.

  • currentValue, the current element being processed in the array.

  • index, the index of the current element being processed in the array.

  • array, the array reduce() was called upon.

  • initialValue

    A value to use as the first argument to the first call of the callback. If no initialValue is supplied, the first element in the array will be used and skipped. Calling reduce() on an empty array without an initialValue will throw a TypeError.

Examples:

// Get sum of an array
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array) {
  return accumulator + currentValue;
});

Custom operations

Filter an Objects Array by fields

filter is an object which defines the filter condition. If an object in the array has the properties with the same values in filter, it will be filtered out.

const filterArray = (arr, filter) => {
  var data = [];
  for (let obj of arr) {
    let filtered = true;
    for (let p in filter) { // for each property in filter
      if (obj[p] != filter[p]) {
        filtered = false;
        break;
      }
    }

    if (filtered) {
      data.push(obj);
    }
  } // for

  return data;
}

Examples:

let employees = [
    {name: 'Jane', gender: 'Female'},
    {name: 'Jim', gender: 'Male' },
    {name: 'Lily', gender: 'Female'}
};
filterArray(employees, {gender: 'Female'});
// [{name: 'Jane', gender: 'Female'}, {name: 'Lily', gender: 'Female'}]

GroupBy

The following groupBy groups objects in an array by a field.

const groupBy = (arr, field) => {
    return arr.reduce(function (acc, obj) {
        let key = obj[field];
        acc[key] = acc[key] || [];
        acc[key].push(obj);
        return acc;
    }, {});
}

Examples:

let employees = [
  {name: 'Jane', gender: 'Female'},
  {name: 'Jim', gender: 'Male' },
  {name: 'Lily', gender: 'Female'}
];
groupBy(employees, 'gender');
// {
//   'Female': [{name: 'Jane', gender: 'Female'}, {name: 'Lily', gender: 'Female'}],
//   'Male': [{name: 'Jim', gender: 'Male' }]
// }

If you want an array of grouped objects:

const groupBy = (arr, field) => {
    let groups = arr.reduce((acc, obj) => {
        let key = obj[field];
        acc[key] = acc[key] || [];
        acc[key].push(obj);
        return acc;
    }, {});

    return Object.keys(groups).map( group => {
        return groups[group];
    });
}

The result will be:

// [
//   [{name: 'Jane', gender: 'Female'}, {name: 'Lily', gender: 'Female'}],
//   [{name: 'Jim', gender: 'Male' }]
// ]

A more generic version

Below code (from javascript codesnipt) is a more generic version. It accepts an array of basic types or objects. It has 2 processes:

  1. Use map to generate a new array. Here arr is the array, and f can be a function or a field name by which it is grouped.
  2. Use reduce function to produce a object in which a field indicates a group.
const groupBy = (arr, f) =>
    arr.map(typeof f === 'function' ? f : val => val[f]).reduce((acc, val, i) => {
        acc[val] = (acc[val] || []).concat(arr[i]);
        return acc;
    }, {});

Examples:

groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}

Of course it can be completed in one loop:

const groupBy = (arr, f) => {
    return arr.reduce((acc, val) => {
        let key = (typeof f === 'function') ? f(val) : val[f]).
        acc[key] = acc[key] || [];
        acc[key].push(val);
        return acc;
    }, {});
}

Union

Union operation returns each item in any of a and b once.

const union = (a, b) => Array.from(new Set([...a, ...b]));

Examples:

union([1, 2, 3], [4, 3, 2]);
// [1,2,3,4]

The union above works only for primitive types. You can provides a comparison function to union other types.

const unionWith = (a, b, comp) =>
    Array.from(new Set([...a, ...b.filter(x => a.findIndex(y => comp(x, y)) === -1)]));

It filters the elements that does not appear in a from b, then makes a merge operation.

Array to Set

let set = new Set(['Apple', 'Banana', 'Apple']);
// ('Apple', 'Banana')

Unique Values in Array

const uniqueValues(arr) => [...new Set(arr)];

shuffle

The modern version implemented in JavaScript of this algorithm (Fisher-Yates Algorithm, from the book The Art of Computer Programming by Donald E. Knuth) goes like:

for(let i = array.length — 1; i > 0; i--){
    const j = Math.floor(Math.random() * i)
    const temp = array[i]
    array[i] = array[j]
    array[j] = temp
}

The Phaser’s shuffle method also uses this algorithm, the source code:

var Shuffle = function (array)
{
    for (var i = array.length - 1; i > 0; i--)
    {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    return array;
};

Note

Below are two examples of when a random algorithm is not random enough:

  • Flaw #1: An Off-by-One Error

    random(n) returns a number between 0 and (n-1), therefore it will never swap the 52nd card with itself; the 52nd card can never end up in the 52nd place.

  • Flaw #2: The Shuffle Isn’t Uniform

    It swaps the ith card with a random card selected from the entire deck. A proper algorithm will swap the ith card only with a card in the interval(i, n) so that each element for a random swap only once.

  • Flaw #3: Using a 32-bit Seed

  • Flaw #4: Using the System Clock as a Seed

And words from Robert Sedgewick, author of Algorithms:

"That's a pretty tough thing to have happen if you're implementing online poker. You might want to make sure that if you're advertising that you're doing a random shuffle that you go ahead and do so."—Robert Sedgewick, Professor of Computer Science, Princeton

When Random Isn’t Random Enough: Lessons from an Online Poker Exploit

This example comes from a 1999 popular online poker platform implemented card-shuffling software. The algorithm used in the shuffling the 52 cards not random engouth:

{ Generate a new seed based on the system clock }
randomize;
{ Randomly rearrange each card }
for ctr := 1 to 52 do begin
random_number := random(51)+1;
tmp := card[random_number];
card[random_number] := card[ctr];
card[ctr] := tmp;
end;

How To Correctly Shuffle An Array in JavaScript

Microsoft had this browser ballot screen on browserchoice.eu where Microsoft was supposed to show all the different browser choices to users in random order. Here is the code they used for doing the random shuffle:

array.sort(function (a, b) { return 0.5 — Math.random() })

But the algorithm was far from random. Here’s an interesting statistical analysis on the results of this algorithm.

More this sort function is also very inefficient, for it gives a very inconsistent ordering which could go into an infinite loop or stop after a few exchanges.

Object to Array

This operation convert an object to an array.

let objectToArray = obj => {
    Object.keys(obj).map(val => {
        return obj[val];
    }
}

Use Array as object to store other properties

An array can be used as an object to store other properties.

let fruits = ['Orange', 'Lemon'];
fruits.kind = 'citrus';

Output an two-dimensional array in a table format

Use join()

let board = [
  ['A','B','C'],
  ['D','E','F'],
  ['G','H','I']
];

console.log(board.join('n'));

Output

A,B,C
D,E,F
G,H,I

Use console.table()

let board = [
  ['A','B','C'],
  ['D','E','F'],
  ['G','H','I']
];

console.log(board.join('n'));

Output

(index) 0 1 2
0 “A” “B” “C”
1 “D” “E” “F”
2 “G” “H” “I”

Reference