Arrays play two roles in JavaScript:

    • Tuples: Arrays-as-tuples have a fixed number of indexed elements. Each of those elements can have a different type.
    • Sequences: Arrays-as-sequences have a variable number of indexed elements. Each of those elements has the same type.
      In reality, there are also mixtures of these two roles.

    Notably, Arrays-as-sequences are so flexible that you can use them as (traditional) arrays, stacks and queues (see exercise at the end of this chapter).

    28.2. Basic Array operations

    28.2.1. Arrays: creating, reading, writing

    The best way to create an Array, is via an Array literal:

    The Array literal starts and ends with square brackets . It creates an Array with three elements: 'a', 'b' and 'c'.

    To read an Array element, you put an index in square brackets (indices start at zero):

    To change an Array element, you assign to an Array with an index:

    1. arr[0] = 'x';

    The range of Array indices is 32 bits (excluding the maximum length): [0, 232−1)

    28.2.2. Arrays: .length

    Every Array has a property .length that can be used to both read and change(!) the number of elements in an Array.

    The length of an Array is always the highest index plus one:

    1. > arr.length

    If you write to the Array at the index of the length, you append an element:

    1. > arr[arr.length] = 'c';
    2. [ 'a', 'b', 'c' ]
    3. 3

    Another way of (destructively) appending an element is via the Array method .push():

    1. > arr

    If you set .length, you are pruning the Array, by removing elements:

    1. > arr.length = 1;
    2. [ 'a' ]

    28.2.3. Spreading into Arrays

    Inside an Array literal, a spread element consists of three dots () followed by an expression. It results in the expression being evaluated and then iterated over. Each iterated value becomes an additional Array element. For example:

    1. > ['a', ...iterable, 'd']

    Spreading is convenient for concatenating Arrays and other iterables into Arrays:

    1. const arr1 = ['a', 'b'];
    2. assert.deepEqual(
    3. ['a', 'b', 'c', 'd', 'e']);

    28.2.4. Arrays: listing indices and entries

    Method .keys() lists the indices of an Array:

    1. const arr = ['a', 'b'];
    2. [...arr.keys()], // (A)

    .keys() returns an iterable. In line A, we spread to obtain an Array.

    Listing Array indices is different from listing properties. When you do the latter, you get the indices – but as strings – plus non-index property keys:

    1. const arr = ['a', 'b'];
    2. Object.keys(arr),

    Method .entries() lists the contents of an Array as [index, element] pairs:

    1. const arr = ['a', 'b'];
    2. [...arr.entries()],

    28.2.5. Is a value an Array?

    These are two ways of checking if a value is an Array:

    1. true
    2. true

    instanceof is usually fine. You need Array.isArray() if a value may come from another realm. Roughly, a realm is an instance of JavaScript’s global scope. Some realms are isolated from each other (e.g. in browsers), but there are also realms between which you can move data (e.g. same-origin iframes in browsers). x instanceof Array checks the prototype chain of x and therefore returns false if x is an Array from another realm.

    typeof categorizes Arrays as objects:

    1. > typeof []

    28.3. for-of and Arrays

    We have already encountered the for-of loop. This section briefly recaps how to use it for Arrays.

    28.3.1. for-of: iterating over elements

    The following for-of loop iterates over the elements of an Array.

    1. for (const element of ['a', 'b']) {
    2. }
    3. // 'a'

    28.3.2. for-of: iterating over [index, element] pairs

    The following for-of loop iterates over [index, element] pairs. Destructuring (described later), gives us convenient syntax for setting up index and element in the head of for-of.

    1. console.log(index, element);
    2. // Output:
    3. // 1, 'b'

    28.4. Array-like objects

    Some operations that work with Arrays, require only the bare minimum: Values must only be Array-like. An Array-like value is an object with the following properties:

    • .length: holds the length of the Array-like object.
    • ['0']: holds the element at index 0. (Etc.)
      A TypeScript interface for ArrayLike looks as follows.
    1. length: number;
    2. }

    Array.from() accepts Array-like objects and converts them to Arrays:

    1. assert.deepEqual(
    2. []);
    3. assert.deepEqual(
    4. [ 'a', 'b' ]);

    Array-like objects used to be common before ES6; now you don’t see them very often.

    There are two common ways of converting iterable and Array-like values to Arrays: spreading and Array.from().

    28.5.1. Converting iterables to Arrays via spreading (…)

    Inside an Array literal, spreading via converts any iterable object into a series of Array elements. For example:

    1. // Get an Array-like collection from a web browser’s DOM
    2. assert.equal('map' in domCollection, false);
    3. // Solution: convert it to an Array
    4. assert.deepEqual(
    5. ['http://2ality.com', 'http://exploringjs.com']);

    The conversion works, because the DOM collection is iterable.

    28.5.2. Converting iterables and Array-like objects to Arrays via Array.from() (advanced)

    Array.from() can be used in two modes.

    28.5.2.1. Mode 1 of Array.from(): converting

    The first mode has the following type signature:

    Interface Iterable is shown in the chapter that introduces iteration. Interface ArrayLike appeared .

    With a single parameter, Array.from() converts anything iterable or Array-like to an Array:

    1. > Array.from(new Set(['a', 'b']))
    2. > Array.from({length: 2, 0:'a', 1:'b'})
    28.5.2.2. Mode 2 of Array.from(): converting and mapping

    The second mode of Array.from() involves two parameters:

    1. iterable: Iterable<T> | ArrayLike<T>,
    2. thisArg?: any)

    In this mode, Array.from() does several things:

    • It iterates over iterable.
    • It applies mapFunc to each iterated value.
    • It collects the results in a new Array and returns it.
      The optional parameter thisArg specifies a this for mapFunc.

    That means that we are going from an iterable with elements of type T to an Array with elements of type U.

    This is an example:

    1. > Array.from(new Set(['a', 'b']), x => x + x)

    28.6. Creating and filling Arrays with arbitrary lengths

    The best way of creating an Array is via an Array literal. However, you can’t always use one: The Array may be too large, you may not know its length during development or you may want to keep its length flexible. Then I recommend the following techniques for creating, and possibly filling, Arrays:

    • Do you need to create an empty Array that you’ll fill completely, later on?
    1. [ , , ,]

    Note that the result has 3 holes – the last comma in an Array literal is always ignored.

    • Do you need to create an Array initialized with a primitive value?
    1. [0, 0, 0]

    Caveat: If you use .fill() with an object then each Array element will refer to the same object.

    • Do you need to create an Array initialized with objects?
    1. [{}, {}, {}]
    • Do you need to create a range of integers?
    1. const END = 5;
    2. Array.from({length: END-START}, (x, i) => i+START),

    If you are dealing with Arrays of integers or floats, consider Typed Arrays – which were created for this purpose.

    28.7. Multidimensional Arrays

    JavaScript does not have real multidimensional Arrays; you need to resort to Arrays whose elements are Arrays:

    1. const DIM_X = 4;
    2. const DIM_Z = 2;
    3. const arr = [];
    4. arr[x] = []; // (A)
    5. arr[x][y] = []; // (B)
    6. arr[x][y][z] = 0; // (C)
    7. }
    8. arr[3][0][1] = 7;
    9. [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ],
    10. [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ],
    11. ]);

    Observations:

    • We grow the Arrays by assigning values to slots whose indices are the current lengths.

    • Each dimension – except the last one – is an Array whose elements are the next dimension (line A, line B).

    • The last dimension contains the actual values (line C).

    28.8. More Array features (advanced)

    In this section, we look at phenomena you don’t encounter that often when working with Arrays.

    28.8.1. Array elements are (slightly special) properties

    You’d think that Array elements are special, because you are accessing them via numbers. But the square brackets operator ([ ]) for doing so, is the same operator that is used for accessing properties. And, according to the language specification, it coerces any value (that is not a symbol) to a string. Therefore: Array elements are (almost) normal properties (line A) and it doesn’t matter if you use numbers or strings as indices (lines B and C):

    1. arr.prop = 123;
    2. Object.keys(arr),
    3. assert.equal(arr['0'], 'a'); // (C)

    To make matters even more confusing, this is only how the language specification defines things (the theory of JavaScript, if you will). Most JavaScript engines optimize under the hood and do use numbers (even integers) to access Array elements (the practice of JavaScript, if you will).

    Property keys (strings!) that are used for Array elements are called indices. A string str is an index if converting it to a 32-bit unsigned integer and back results in the original value. Written as a formula:

    1. ToString(ToUint32(key)) === key
    1. arr.prop = 123;
    2. Object.keys(arr),

    Note that .length, .entries() and .keys() treat Array indices as numbers and ignore non-index properties:

    1. const arr = ['a', 'b'];
    2. Object.keys(arr), ['0', '1', 'prop']);
    3. assert.equal(arr.length, 2);
    4. [...arr.keys()], [0, 1]);
    5. [...arr.entries()], [[0, 'a'], [1, 'b']]);

    We used a spread element () to convert the iterables returned by .keys() and .entries() to Arrays.

    28.8.2. Arrays are dictionaries and can have holes

    JavaScript supports two kinds of Arrays:

    • Dense Arrays: are Arrays whose elements form a contiguous sequence. That is the only kind of Array we have seen so far.
    • Sparse Arrays: are Arrays that have holes in them. That is, some indices are missing.
      In general, it’s best to avoid holes, because they make your code more complicated and are not handled consistently by Array methods. Additionally, JavaScript engines optimize dense Arrays, so they are faster.

    You can create holes by skipping indices when assigning elements:

    1. const arr = [];
    2. arr[2] = 'c';
    3. assert.deepEqual(Object.keys(arr), ['0', '2']); // (A)
    4. assert.equal(0 in arr, true); // element

    In line A, we are using Object.keys(), because arr.keys() treats holes as if they were undefined elements and does not reveal them.

    Another way of creating holes is to skip elements in Array literals:

    1. const arr = ['a', , 'c'];
    2. assert.deepEqual(Object.keys(arr), ['0', '2']);

    And you can delete Array elements:

    1. assert.deepEqual(Object.keys(arr), ['0', '1', '2']);
    2. assert.deepEqual(Object.keys(arr), ['0', '2']);

    For more information on how JavaScript handles holes in Arrays, consult .

    JavaScript’s Array is quite flexible and more like a combination of array, stack and queue. This section explores ways of adding and removing Array elements. Most operations can be performed both destructively (modifying the Array) and non-destructively (producing a modified copy).

    28.9.1. Prepending elements and Arrays

    In the following code, we destructively prepend single elements to arr1 and an Array to arr2:

    1. arr1.unshift('x', 'y'); // prepend single elements
    2. const arr2 = ['a', 'b'];
    3. assert.deepEqual(arr2, ['x', 'y', 'a', 'b']);

    Spreading lets us unshift an Array into arr2.

    Non-destructive prepending is done via spread elements:

    28.9.2. Appending elements and Arrays

    In the following code, we destructively append single elements to arr1 and an Array to arr2:

    1. const arr1 = ['a', 'b'];
    2. assert.deepEqual(arr1, ['a', 'b', 'x', 'y']);
    3. const arr2 = ['a', 'b'];
    4. assert.deepEqual(arr2, ['a', 'b', 'x', 'y']);

    Spreading lets us push an Array into arr2.

    Non-destructive appending is done via spread elements:

    1. assert.deepEqual(
    2. ['a', 'b', 'x', 'y']);
    3. assert.deepEqual(
    4. ['a', 'b', 'x', 'y']);

    28.9.3. Removing elements

    These are three destructive ways of removing Array elements:

    1. const arr1 = ['a', 'b', 'c'];
    2. assert.deepEqual(arr1, ['b', 'c']);
    3. // Destructively remove last element:
    4. assert.equal(arr2.pop(), 'c');
    5. const arr3 = ['a', 'b', 'c'];
    6. assert.deepEqual(arr3, ['a', 'c']);

    .splice() is covered in more detail in .

    Destructuring via a rest element lets you non-destructively remove elements from the beginning of an Array (destructuring is covered later).

    1. const arr1 = ['a', 'b', 'c'];
    2. const [, ...arr2] = arr1;
    3. assert.deepEqual(arr1, ['a', 'b', 'c']); // unchanged!

    Alas, a rest element must always come last in an Array. Therefore, you can only use it to extract suffixes.

    28.10. Methods: iteration and transformation (.find(), .map(), .filter(), etc.)

    In this section, we take a look at Array methods for iterating over Arrays and for transforming Arrays. Before we do so, let’s consider two different approaches for iteration. It will help us understand how the methods work.

    28.10.1. External iteration vs. internal iteration

    Let’s assume that your code wants to iterate over the values “inside” an object. Two common approaches for doing that, are:

    • External iteration (pull): Your code asks the object for the values, via an iteration protocol. For example, the for-of loop is based on JavaScript’s iteration protocol:
    1. console.log(x);
    2. // Output:
    3. // 'b'

    For a longer example, consult .

    • Internal iteration (push): You pass a callback function to a method of the object and the method feeds the values to the callback. For example, Arrays have the method .forEach():
    1. console.log(x);
    2. // Output:
    3. // 'b'

    For a longer example, consult .

    The methods that we are looking at next, all use internal iteration.

    28.10.2. Callbacks for iteration and transformation methods

    Callbacks for methods that iterate or transform, have signatures such as:

    That is, the callback gets three parameters (it is free to ignore any of them):

    • value is the most important one. This parameter holds the iterated value that is currently being processed.
    • index can additionally tell the callback what the index of the iterated value is.
    • array points to the current Array (the receiver of the method call). Some algorithms need to refer to the whole Array – e.g. to search it for answers. This parameter lets you write reusable callbacks for such algorithms.
      What the callback is expected to return, depends on the method it is passed to. Possibilities include:

    • Nothing (.forEach()).

    • A boolean (.find()).
    • An arbitrary value (.map()).

    28.10.3. Searching elements: .find(), .findIndex()

    .find() returns the first element for which its callback returns a truthy value:

    1. -5
    2. undefined

    .findIndex() returns the index of the first element for which its callback returns a truthy value:

    1. 1
    2. -1

    .findIndex() can be implemented as follows:

    1. for (const [i, x] of arr.entries()) {
    2. return i;
    3. }
    4. }
    5. assert.equal(1, findIndex(['a', 'b', 'c'], x => x === 'b'));

    28.10.4. .map(): copy while giving elements new values

    .map() returns a copy of the receiver. The elements of the copy are the results of applying map’s callback parameter to the elements of the receiver.

    All of this is easier to understand via examples:

    1. > [1, 2, 3].map(x => x * 3)
    2. > ['how', 'are', 'you'].map(str => str.toUpperCase())
    3. > [true, true, true].map((_, index) => index)

    Note: _ is just another variable name.

    .map() can be implemented as follows:

    1. function map(arr, mapFunc) {
    2. for (const [i, x] of arr.entries()) {
    3. }
    4. }
    5. assert.deepEqual(
    6. ['0.a', '1.b', '2.c']);

    28.10.5. .flatMap(): mapping to zero or more values

    The type signature of Array<T>.prototype.flatMap() is:

    1. .flatMap<U>(
    2. thisValue?: any

    Both .map() and .flatMap() take a function f as a parameter that controls how an input Array is translated to an output Array:

    • With .map(), each input Array element is translated to exactly one output element. That is, f returns a single value.
    • With .flatMap(), each input Array element is translated to zero or more output elements. That is, f returns an Array of values (it can also return non-Array values, but that is rare).
      This is .flatMap() in action:
    1. > ['a', 'b', 'c'].flatMap(x => [x,x])
    2. > ['a', 'b', 'c'].flatMap(x => [x])
    3. > ['a', 'b', 'c'].flatMap(x => [])
    28.10.5.1. A simple implementation

    You could implement .flatMap() as follows. Note: this implementation is simpler than the built-in version, which, e.g., performs more checks.

    1. const result = [];
    2. const x = mapFunc(elem, index, arr);
    3. if (Array.isArray(x)) {
    4. } else {
    5. }
    6. return result;

    What is .flatMap() good for? Let’s look at use cases!

    28.10.5.2. Use case: filtering and mapping at the same time

    The result of the Array method .map() always has the same length as the Array it is invoked on. That is, its callback can’t skip Array elements it isn’t interested in.

    The ability of .flatMap() to do so is useful in the next example: processArray() returns an Array where each element is either a wrapped value or a wrapped error.

    1. return arr.map(x => {
    2. return { value: process(x) };
    3. return { error: e };
    4. });

    The following code shows processArray() in action:

    1. let err;
    2. if (value < 0) {
    3. }
    4. }
    5. assert.deepEqual(results, [
    6. { error: err },
    7. ]);

    .flatMap() enables us to extract just the values or just the errors from results:

    1. result => result.value ? [result.value] : []);
    2. result => result.error ? [result.error] : []);
    28.10.5.3. Use case: mapping to multiple values

    The Array method .map() maps each input Array element to one output element. But what if we want to map it to multiple output elements?

    That becomes necessary in the following example:

    • Input: ['a', 'b', 'c']
    • Output: ['<span>a</span>', ', ', '<span>b</span>', ', ', '<span>c</span>']
      The function wrap() that makes this transformation is similar to code you write for the frontend library React:
    1. return tags.flatMap(
    2. const html = `<span>${tag}</span>`;
    3. return [html];
    4. return [', ', html];
    5. }
    6. }
    7. assert.deepEqual(
    8. ['<span>a</span>', ', ', '<span>b</span>', ', ', '<span>c</span>']

    28.10.6. .filter(): only keep some of the elements

    The Array method .filter() returns an Array collecting all elements for which the callback returns a truthy value.

    For example:

    1. [ 2, 5, 6 ]
    2. [ 'a', 'c' ]

    .filter() can be implemented as follows:

    1. const result = [];
    2. if (filterFunc(x, i, arr)) {
    3. }
    4. return result;
    5. filter([ 1, 'a', 5, 4, 'x'], x => typeof x === 'number'),
    6. assert.deepEqual(
    7. ['a', 'x']);

    28.10.7. .reduce(): deriving a value from an Array (advanced)

    Method .reduce() is a powerful tool for computing a “summary” of an Array. A summary can be any kind of value:

    • A number. For example, the sum of all Array elements.
    • An Array. For example, a copy of the Array, with elements multiplied by 2.
    • Etc.
      This operation is also known as foldl (“fold left”) in functional programming and popular there. One caveat is that it can make code difficult to understand.

    .reduce() has the following type signature (inside an Array<T>):

    1. .reduce<U>(
    2. init?: U)

    T is the type of the Array elements, U is the type of the summary. The two may or may not be different. accumulator is just another name for “summary”.

    To compute the summary of an Array arr, .reduce() feeds all Array elements to its callback, one at a time:

    1. const accumulator_0 = callback(init, arr[0]);
    2. const accumulator_2 = callback(accumulator_1, arr[2]);

    callback combines the previously computed summary (stored in its parameter accumulator) with the current Array element and returns the next accumulator. The result of .reduce() is the final accumulator – the last result of callback, after it has visited all elements.

    In other words: callback does most of the work, .reduce() just invokes it in a useful manner.

    You could say that the callback folds Array elements into the accumulator. That’s why this operation is called “fold” in functional programming.

    28.10.7.1. A first example

    Let’s look at an example of .reduce() in action: function addAll() computes the sum of all numbers in an Array arr.

    1. const startSum = 0;
    2. return arr.reduce(callback, startSum);
    3. assert.equal(addAll([1, 2, 3]), 6); // (A)

    How was the result 6 derived from the Array in line A? Via the following invocations of callback:

    1. callback(0, 1) --> 1
    2. callback(1, 2) --> 3
    3. callback(3, 3) --> 6

    Notes:

    • The first parameters are the current accumulators (starting with parameter init of .reduce()).
    • The second parameters are the current Array elements.
    • The results are the next accumulators.
    • The last result of callback is also the result of .reduce().
      Alternatively, we could have implemented addAll() via a for-of loop:
    1. function addAll(arr) {
    2. for (const element of arr) {
    3. }
    4. }

    It’s hard to say which of the two implementations is “better”: The one based on .reduce() is a little more concise, while the one based on for-of may be a little easier to understand – especially if you are not familiar with functional programming.

    28.10.7.2. Example: finding indices via .reduce()

    The following function is an implementation of the Array method .indexOf(). It returns the first index at which the given searchValue appears inside the Array arr:

    1. const NOT_FOUND = -1;
    2. return arr.reduce(
    3. if (result !== NOT_FOUND) {
    4. return result;
    5. return index;
    6. return NOT_FOUND;
    7. NOT_FOUND);
    8. assert.equal(indexOf(['a', 'b', 'c'], 'b'), 1);

    One limitation of .reduce() is that you can’t finish early (in a for-of loop, you can break). Here, we don’t do anything once we have found what we were looking for.

    28.10.7.3. Example: doubling Array elements

    Function double(arr) returns a copy of inArr whose elements are all multiplied by 2:

    1. return inArr.reduce(
    2. outArr.push(element * 2);
    3. },
    4. }
    5. double([1, 2, 3]),

    We modify the initial value [] by pushing into it. A non-destructive, more functional version of double() looks as follows:

    1. function double(inArr) {
    2. // Don’t change `outArr`, return a fresh Array
    3. []);
    4. assert.deepEqual(
    5. [2, 4, 6]);

    This version is more elegant, but also slower and uses more memory.

    28.11. .sort(): sorting Arrays

    .sort() has the following type definition:

    .sort() always sorts string representations of the elements. These representations are compared via <. This operator compares lexicographically (the first characters are most significant). You can see that when comparing numbers:

    1. > [200, 3, 10].sort()

    When comparing human-language strings, you need to be aware that they are compared according to their code unit values (char codes):

    1. > ['pie', 'cookie', 'éclair', 'Pie', 'Cookie', 'Éclair'].sort()

    As you can see, all unaccented uppercase letters come before all unaccented lowercase letter, which come before all accented letters. Use Intl, the JavaScript internationalization API, if you want proper sorting for human languages.

    Lastly, .sort() sorts in place: it changes and returns its receiver:

    1. > arr.sort() === arr
    2. > arr

    28.11.1. Customizing the sort order

    You can customize the sort order via the parameter, compareFunc, which returns a number that is:

    • negative if a < b
    • zero if a === b
    • positive if a > b
      Tip for remembering these rules: a negative number is less than zero (etc.).

    28.11.2. Sorting numbers

    You can use the following helper function to compare numbers:

    1. function compareNumbers(a, b) {
    2. return -1;
    3. return 0;
    4. return 1;
    5. }
    6. [200, 3, 10].sort(compareNumbers),

    The following is a quick and dirty alternative. Its downsides are that it is cryptic and that there is a risk of numeric overflow:

    1. > [200, 3, 10].sort((a,b) => a-b)

    28.11.3. Sorting objects

    You also need to use a compare function if you want to sort objects. As an example, the following code shows how to sort objects by age.

    28.12. Quick reference: Array<T>

    Legend:

    • R: method does not change the receiver (non-destructive).
    • W: method changes the receiver (destructive).

    28.12.1. new Array()

    new Array(n) creates an Array of length n, that contains n holes:

    1. // Therefore: number of commas = number of holes

    new Array() creates an empty Array. However, I recommend to always use [], instead.

    28.12.2. Static methods of Array

    • Array.from<T>(iterable: Iterable<T> | ArrayLike<T>): T[] [ES6]

    • Array.from<T,U>(iterable: Iterable<T> | ArrayLike<T>, mapFunc: (v: T, k: number) => U, thisArg?: any): U[] [ES6]

    Converts an iterable or an Array-like object to an Array. Optionally, the input values can be translated via a mapFunc before they are added to the output Array.

    An Array-like object has a .length and index properties (roughly, string representations of non-negative integers):

    1. length: number;
    2. }

    Examples:

    1. [ 'a', 'b' ]
    2. [ 'a', 'b' ]
    • Array.of<T>(…items: T[]): T[] [ES6]

    This static method is mainly useful for subclasses of Array and Typed Arrays, where it serves as a custom Array literal:

    1. Uint8Array.of(1, 2, 3) instanceof Uint8Array, true);

    28.12.3. Methods of Array<T>.prototype

    • .concat(…items: Array<T[] | T>): T[] [R, ES3]

    Returns a new Array that is the concatenation of the receiver and all items. Non-Array parameters are treated as if they were Arrays with single elements.

    1. > ['a'].concat('b', ['c', 'd'])
    • .copyWithin(target: number, start: number, end=this.length): this [W, ES6]

    Copies the elements whose indices range from start to (excl.) end to indices starting with target. Overlapping is handled correctly.

    1. > ['a', 'b', 'c', 'd'].copyWithin(0, 2, 4)
    • .entries(): Iterable<[number, T]> [R, ES6]

    Returns an iterable over [index, element] pairs.

    1. > Array.from(['a', 'b'].entries())
    • .every(callback: (value: T, index: number, array: Array<T>) => boolean, thisArg?: any): boolean [R, ES5]

    Returns true if callback returns true for every element and false, otherwise. Stops as soon as it receives false. This method corresponds to universal quantification (for all, ) in mathematics.

    1. > [1, 2, 3].every(x => x > 0)
    2. > [1, -2, 3].every(x => x > 0)
    • .fill(value: T, start=0, end=this.length): this [W, ES6]

    Assigns value to every index between (incl.) start and (excl.) end.

    1. > [0, 1, 2].fill('a')
    • .filter(callback: (value: T, index: number, array: Array<T>) => any, thisArg?: any): T[] [R, ES5]

    Returns an Array with only those elements for which callback returns true.

    1. > [1, -2, 3].filter(x => x > 0)
    • .find(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): T | undefined [R, ES6]

    The result is the first element for which predicate returns true. If it never does, the result is undefined.

    1. > [1, -2, 3].find(x => x < 0)
    2. > [1, 2, 3].find(x => x < 0)
    • .findIndex(predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): number [R, ES6]

    The result is the index of the first element for which predicate returns true. If it never does, the result is -1.

    1. > [1, -2, 3].findIndex(x => x < 0)
    2. > [1, 2, 3].findIndex(x => x < 0)
    • .flat(depth = 1): any[] [R, ES2019]

    “Flattens” an Array: It creates a copy of the Array where values in nested Arrays all appear at the top level. The parameter depth controls how deeply .flat() looks for non-Array values.

    1. > [ 1,2, [3,4], [[5,6]] ].flat(0) // no change
    2. [ 1, 2, 3, 4, [ 5, 6 ] ]
    3. > [ 1,2, [3,4], [[5,6]] ].flat(2)
    • .flatMap<U>(callback: (value: T, index: number, array: T[]) => U|Array<U>, thisValue?: any): U[] [R, ES2019]

    The result is produced by invoking callback() for each element of the original Array and concatenating the Arrays it returns.

    1. > ['a', 'b', 'c'].flatMap(x => [x,x])
    2. > ['a', 'b', 'c'].flatMap(x => [x])
    3. > ['a', 'b', 'c'].flatMap(x => [])
    • .forEach(callback: (value: T, index: number, array: Array<T>) => void, thisArg?: any): void [R, ES5]

    Calls callback for each element.

    1. ['a', 'b'].forEach((x, i) => console.log(x, i))
    2. // Output:
    3. // 'b', 1
    • .includes(searchElement: T, fromIndex=0): boolean [R, ES2016]

    Returns true if the receiver has an element whose value is searchElement and false, otherwise. Searching starts at index fromIndex.

    1. true
    2. false
    • .indexOf(searchElement: T, fromIndex=0): number [R, ES5]

    Returns the index of the first element that is strictly equal to searchElement. Returns -1 if there is no such element. Starts searching at index fromIndex, visiting higher indices next.

    1. 0
    2. 2
    3. -1
    • .join(separator = ','): string [R, ES1]

    Creates a string by concatenating string representations of all elements, separating them by separator.

    1. 'a##b##c'
    2. 'a,b,c'
    • .keys(): Iterable<number> [R, ES6]

    Returns an iterable over the keys of the receiver.

    1. [ 0, 1 ]
    • .lastIndexOf(searchElement: T, fromIndex=this.length-1): number [R, ES5]

    Returns the index of the last element that is strictly equal to searchElement. Returns -1 if there is no such element. Starts searching at index fromIndex, visiting lower indices next.

    1. 2
    2. 0
    3. -1
    • .map<U>(mapFunc: (value: T, index: number, array: Array<T>) => U, thisArg?: any): U[] [R, ES5]

    Returns a new Array, in which every element is the result of mapFunc being applied to the corresponding element of the receiver.

    1. [ 2, 4, 6 ]
    2. [ 0, 1, 2 ]
    • .pop(): T | undefined [W, ES3]

    Removes and returns the last element of the receiver. That is, it treats the end of the receiver as a stack. The opposite of .push().

    1. > arr.pop()
    2. > arr
    • .push(…items: T[]): number [W, ES3]

    Adds zero or more items to the end of the receiver. That is, it treats the end of the receiver as a stack. The return value is the length of the receiver after the change. The opposite of .pop().

    1. > const arr = ['a', 'b'];
    2. 4
    3. [ 'a', 'b', 'c', 'd' ]
    • .reduce<U>(callback: (accumulator: U, element: T, index: number, array: T[]) => U, init?: U): U [R, ES5]

    This method produces a summary of the receiver: It feeds all Array elements to callback, which combines a current intermediate result (in parameter accumulator) with the current Array element and returns the next accumulator:

    1. const accumulator_1 = callback(accumulator_0, arr[1]);
    2. // Etc.

    The result of .reduce() is the last result of callback, after it has visited all Array elements.

    If no init is provided, the Array element at index 0 is used, instead.

    1. 6
    2. '123'
    • .reduceRight<U>(callback: (accumulator: U, element: T, index: number, array: T[]) => U, init?: U): U [R, ES5]

    Works like .reduce(), but visits the Array elements backward, starting with the last element.

    1. '321'
    • .reverse(): this [W, ES1]

    Rearranges the elements of the receiver so that they are in reverse order and then returns the receiver.

    1. > arr.reverse()
    2. > arr
    • .shift(): T | undefined [W, ES3]

    Removes and returns the first element of the receiver. The opposite of .unshift().

    1. > const arr = ['a', 'b', 'c'];
    2. 'a'
    3. [ 'b', 'c' ]
    • .slice(start=0, end=this.length): T[] [R, ES3]

    Returns a new Array, containing the elements of the receiver whose indices are between (incl.) start and (excl.) end.

    1. [ 'b', 'c' ]
    2. [ 'a', 'b' ]
    • .some(callback: (value: T, index: number, array: Array<T>) => boolean, thisArg?: any): boolean [R, ES5]

    Returns true if callback returns true for at least one element and false, otherwise. Stops as soon as it receives true. This method corresponds to existential quantification (exists, ) in mathematics.

    1. false
    2. true
    • .sort(compareFunc?: (a: T, b: T) => number): this [W, ES1]

    Sorts the receiver and returns it. Since ECMAScript 2019, sorting is guaranteed to be stable: If elements are considered equal by sorting then sorting does not change the order of those elements (relative to each other).

    By default, it sorts string representations of the elements. It does so lexicographically and according to the code unit values (char codes) of the characters:

    1. [ 'Cookie', 'Pie', 'cookie', 'pie', 'Éclair', 'éclair' ]
    2. [ 10, 200, 3 ]

    You can customize the sort order via compareFunc, which returns a number that is:

    • negative if a < b
    • zero if a === b
    • positive if a > b
      Trick for sorting numbers (with a risk of numeric overflow):
    1. [ 3, 10, 200 ]
    • .splice(start: number, deleteCount=this.length-start, …items: T[]): T[] [W, ES3]

    At index start, it removes deleteCount elements and inserts the items. It returns the deleted elements.

    1. > arr.splice(1, 2, 'x', 'y')
    2. > arr
    • .toString(): string [R, ES1]

    Returns a string with the stringifications of all elements, separated by commas.

    1. > [1, 2, 3].toString()
    2. > ['a', 'b', 'c'].toString()
    3. > [].toString()
    • .unshift(…items: T[]): number [W, ES3]
    1. > const arr = ['c', 'd'];
    2. 4
    • .values(): Iterable<T> [R, ES6]

    Returns an iterable over the values of the receiver.

    28.12.4. Sources