Array destructuring

Destructuring assignment

We covered the destructuring assignment before, in the chapter about object destructuring. In this section we will explore the destructuring assignment syntax specifically used to unpack elements from arrays into distinct variables. Array destructuring calls the iterator of the right-hand side of the statement.

The next example shows array destructuring via a binding pattern, i.e., the assignment starts with a declaration keyword (const in the example below). All variables, or constants in this case, share the same declaration.


const myArray = [1, 2, 3, 4, 5];
const [x, y] = myArray;

// is equivalent to:
// const x = myArray[0];
// const y = myArray[1];

console.log(x); // logs: 1
console.log(y); // logs: 2

The next example shows array destructuring via an assignment pattern, i.e., variables or properties are declared elsewhere in the code.


const myArray = [1, 2, 3, 4, 5];
let x, y;

[ x, y ] = myArray;

// is equivalent to:
// let x, y;
// x = myArray[0];
// y = myArray[1];

console.log(x); // logs: 1
console.log(y); // logs: 2

Array destructuring calls the iterator method of the object on the right-hand side. Therefore, any iterable, not necessarily arrays, can be destructured.


// A string primitive is iterable via the String wrapper object: 
const [x, y] = "Hello";
console.log(x); // logs: "H"
console.log(y); // logs: "e"

// A set is iterable (will be covered later in this tutorial):
const [a, b] = new Set([1, 2]);
console.log(a); // logs: 1
console.log(b); // logs: 2

// A customised iterable:
const myIterable = {
  *[Symbol.iterator]() {
    for (const i of [0, 1, 2, 3]) {
      yield i;
    }
  },
}
const [...rest] = myIterable;
console.log(rest); // logs [ 0, 1, 2, 3 ] // an array!

PS. Sets are iterables and will be explained in a later chapter.

Examples

Skipping elements


const myArray = [1, 2, 3];
const [a, , b] = myArray;

console.log(a); // logs: 1
console.log(b); // logs: 3

More variables than elements


const [father, mother, daughter = "Abby", son] = ['Jake', 'Linda'];
console.log(father); // logs: "Jake"
console.log(mother); // logs: "Linda"
console.log(daughter); // logs: "Abby"
console.log(son);  // logs: undefined

Swapping variables


let a = 1;
let b = 3;

[a, b] = [b, a];
console.log(a); // logs: 3
console.log(b); // logs: 1

BTW. We have applied this method in an iterative implementation of the Euclidean algorithm when we covered tail recursion.

Altering an array

With assignment patterns, you can assign to a property or element instead of to a variable or constant.


const myArray = [ 1, 2 ];
let a; const c = [];

[ a, c[0] ] = myArray;

// is equivalent to:
// let a; const c = [];
// a = myArray[0];
// c[0] = myArray[1];

console.log(a); // logs: 1
console.log(c); // logs: [ 2 ]

const myArray = [ 1, 2 ];
let a; const c = {};

[ a, c.d ] = myArray;

// is equivalent to:
// let a; const c = {};
// a = myArray[0];
// c.d = myArray[1];

console.log(a); // logs: 1
console.log(c); // logs: { d: 2 }

const myArray = [1, 2, 3];
[myArray[1], myArray[2]] = [myArray[2], 5];
console.log(myArray); // logs: [ 1, 3, 5 ]

Copying an array

See also Array destructuring and rest elements


const myArray = [1, 2, 3];
const [...copiedArray] = myArray;
console.log(copiedArray)     // logs: [ 1, 2, 3 ] // an array!

The rest property (or rest element in this context) gets a new array assigned, instead of an object as with object destructuring.

Destructuring nested arrays and objects


const somePerson = {
  fullName: { firstName: "Jane", LastName: "Doe" },
  degrees: ["BSc", "MSc", "PhD"]
}

const {
  fullName: { firstName: name },
  degrees: [ , secondDegree, ]
} = somePerson;

console.log(`The second degree ${name} received is a ${secondDegree} degree.`);
// logs: "The second degree Jane received is a MSc degree."

const users = [
  { id: 1, name: 'Jane'},
  { id: 2, name: 'Joe'},
  { id: 3, name: 'Jill'}
];

const [,, { name }] = users;

console.log(name); // logs: "Jill"

Destructuring an array returned from a function


function myFunction() { return [1, 2]; }

const [a, b] = myFunction();
console.log(a); // logs: 1
console.log(b); // logs: 2

Destructured function parameter

Function parameters can be arrays or objects to be unpacked into local variables. This has been covered before when we went over object destructuring.


function add([x = 1, y = 2] = []) {
  return x + y;
}

console.log(add()); // logs: 3
console.log(add([])); // logs: 3
console.log(add([2])); // logs: 4
console.log(add([2, 3])); // logs: 5

for...of iteration and destructuring

This has been covered before when we went over object destructuring.


const people = [
  {
    title: "Miss", 
    fullName: { firstName: "Jane", lastName: "Doe" },
    age: 23,
  },
  {
    title: "Mr",
    fullName: { firstName: "John", lastName: "Smith" },
    age: 29,
  }
];

for (const { title, fullName: { lastName } } of people) {
  console.log(`${title} ${lastName}`);
}
// logs:
// "Miss Doe"
// "Mr Smith"

To get the array index of each iteration in a for...of loop you typically will need something additional like a counter. But it can also be done with array destructuring and the Array.prototype.entries() method. The Array.prototype.entries() method returns a new array that contains all the key-value pairs for each item in the array.


const myArray = ['pit','pot','pet'];

for(const [index,value] of myArray.entries()){
    console.log(`#${index}: ${value}`);
}

// logs:
// "#0: pit"
// "#1: pot"
// "#2: pet"