ndarray-methods

Convenient methods for JavaScript built-in multi-dimensional arrays.

Usage no npm install needed!

<script type="module">
  import ndarrayMethods from 'https://cdn.skypack.dev/ndarray-methods';
</script>

README

ndarray-methods

npm types license

Convenient methods for JavaScript built-in multi-dimensional arrays.

Zero dependencies. Written in TypeScript.

Installation

npm install ndarray-methods

Via CDN

Library Style

<script src="https://unpkg.com/ndarray-methods@1.1.0/dist/index.js" defer></script>

Polyfill Style

<script src="https://unpkg.com/ndarray-methods@1.1.0/dist/polyfill.js" defer></script>

You don't need to include both of the above, just choose your preferred style.

Using NDArray

Library Style

import NDArray from "ndarray-methods";

function levenshteinDistance(s, t) {
  return NDArray.nestedFillMap(
    NDArray.buildShape(
      [s.length + 1, t.length + 1],
      (i, j) => +!(i && j) && (i || j)
    ),
    (_, [i, j], d) => Math.min(
      d[i - 1][j] + 1,
      d[i][j - 1] + 1,
      d[i - 1][j - 1] + (s[i - 1] != t[j - 1])
    ),
    [1, 1]
  )[s.length][t.length];
}

levenshteinDistance("kitten", "sitting"); // 3

Polyfill Style

To use the library as a "polyfill" on Array.prototype:

import "ndarray-methods/polyfill";

function levenshteinDistance(s, t) {
  return [s.length + 1, t.length + 1]
    .buildShape((i, j) => +!(i && j) && (i || j))
    .nestedFillMap(
      (_, [i, j], d) => Math.min(
        d[i - 1][j] + 1,
        d[i][j - 1] + 1,
        d[i - 1][j - 1] + (s[i - 1] != t[j - 1])
      ),
      [1, 1]
    )[s.length][t.length];
}

levenshteinDistance("kitten", "sitting"); // 3

Type Inferring

It is recommended that you use a tuple() utility function while handling with shape or coordinates (or TypeScript's as const, whatever you want) to infer the more accurate type especially when using TypeScript:

[3, 4, 5].buildShape(0); // Inferred type: NDArray<number>
tuple(3, 4, 5).buildShape(0); // Inferred type: number[][][]

To define the tuple() function:

function tuple<T extends unknown[]>(...args: T) { return args; }

Or if you're not using TypeScript:

/** @type { <T extends unknown[]>(...args: T) => T } */
function tuple(...args) { return args; }

Notes

  • This library is intended to extend the built-in Array.prototype (because it may become a library for demonstration for the planned ECMAScript Proposal), so many methods are prefixed with the word nested.

  • The documentation is written based on the declaration files of the core library, so as to keep the wording consistent with the ECMAScript specification.

  • The types in the documentation are wide; you should get narrower types when you are writing codes.

Documentation

Table of Contents

Methods

buildShape

array<T>.buildShape(mapfn, thisArg?): NDArray<T>

Builds a nested array with a specific shape and fills the array with the result of a defined map function.

[2, 3].buildShape((x, y) => x * 3 + y); // [[0, 1, 2], [3, 4, 5]]

Parameters

Name Type Description
array number[] The shape of the array.
mapfn (...indices: number[]) => T A function that accepts the coordinates of the element. The buildShape method calls the mapfn function one time for each position in the array.
thisArg? any An object to which the this keyword can refer in the mapfn function. If thisArg is omitted, undefined is used as the this value.

Returns

NDArray<T>

The array built with the specific shape.


array<T>.buildShape(value): NDArray<T>

Builds a nested array with a specific shape and fills the array with a static value.

[2, 3].buildShape(10); // [[10, 10, 10], [10, 10, 10]]

Parameters

Name Type Description
array number[] The shape of the array.
value T The value to fill the array with.

Returns

NDArray<T>

The array built with the specific shape.


shape, shapeAtOrigin

array.shape(): number[]

Gets the length of each axis of a nested array. The shape method returns the shape at the deepest element.

[[0, 1, 2], [3, 4, 5]].shape(); // [2, 3]
[[0, 1], [2, [3, 4], 5]].shape(); // [2, 3, 2]

array.shapeAtOrigin(): number[]

Gets the length of each axis of a nested array. The shapeAtOrigin method only checks the first element recursively.

[[0, 1, 2], [3, 4, 5]].shapeAtOrigin(); // [2, 3]
[[0, 1], [2, [3, 4], 5]].shapeAtOrigin(); // [2, 2]

Parameters

Name Type Description
array NDArray<unknown> The original array.

Returns

number[]

A number array containing the lengths of each axis of the array.


nestedMap

array<T>.nestedMap<U>(callbackfn, thisArg?): NDArray<U>

Calls a defined callback function on each element in a nested array, and returns a deeply-cloned array that contains the results.

[[0, 1, 2], [3, 4, 5]].nestedMap(n => n + 10); // [[10, 11, 12], [13, 14, 15]]

Parameters

Name Type Description
array NDArray<T> The original array.
callbackfn (value: T, index: number[], array: NDArray<T>, parent: NDArray<T>) => U A function that accepts up to 4 arguments. The nestedMap method calls the callbackfn function one time for each element in the array.
thisArg? any An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.

Returns

NDArray<U>

The mapped array.


nestedForEach

array<T>.nestedForEach<U>(callbackfn, thisArg?): void

Performs the specified action for each element in a nested array.

[[0, 1, 2], [3, 4, 5]].nestedForEach(n => console.log(n)); // Prints 0 to 5

Parameters

Name Type Description
array NDArray<T> The original array.
callbackfn (value: T, index: number[], array: NDArray<T>, parent: NDArray<T>) => U A function that accepts up to 4 arguments. The nestedForEach method calls the callbackfn function one time for each element in the array.
thisArg? any An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.

nestedSplit

separators.nestedSplit(content): NDArray<string>

Splits a string into substrings using the specified separators for each axis and return them as a nested array.

[/,|;/, ""].nestedSplit("AB,CD;EF"); // [["A", "B"], ["C", "D"], ["E", "F"]]

Parameters

Name Type Description
separators (string | RegExp)[] An array of separators to use in separating the string.
content string The string to split.

Returns

NDArray<string>

The splitted string as a nested array.


nestedJoin

separators.nestedJoin(content): string

Concatenates all the elements in a nested array into a string, separated by the specified separator strings for each axis.

[",", ""].nestedJoin([[0, 1, 2], [3, 4, 5]]); // "012,345"

Parameters

Name Type Description
separators string[] A string used to separate one element of the array from the next in the resulting string. If a certain separator is undefined, a comma (,) is used instead for that axis.
content NDArray<unknown> The array to join.

Returns

string

A string with all the elements concatenated.


nestedFill

array<T>.nestedFill(value, startIndices?, endIndices?): NDArray<T>

Changes all elements in a nested array from startIndices to endIndices to a static value in place and returns the array.

[[0, 1, 2], [3, 4, 5]].nestedFill(10); // [[10, 10, 10], [10, 10, 10]]
[[0, 1, 2], [3, 4, 5]].nestedFill(10, [0, 0], [2, 2]); // [[10, 10, 2], [10, 10, 5]]

If both startIndices and endIndices are omitted, all the elements will be replaced to the specified value.

Parameters

Name Type Description
array NDArray<T> The original array.
value T The value to fill the section of the array with.
startIndices? number[] The coordinates to start filling the array at (inclusive). If a certain start index is negative, the length of that axis of the array will be added to it.
endIndices? number[] The coordinates to stop filling the array at (exclusive). If a certain end index is negative, the length of that axis of the array will be added to it.

Returns

NDArray<T>

The modified array, which the instance is the same as the original array.


nestedFillMap

array<T>.nestedFillMap(callbackfn, startIndices?, endIndices?, thisArg?): NDArray<T>

Calls a defined callback function on all elements in a nested array from startIndices to endIndices in place and returns the array.

[[0, 1, 2], [3, 4, 5]].nestedFillMap(n => n + 10); // [[10, 11, 12], [13, 14, 15]]
[[0, 1, 2], [3, 4, 5]].nestedFillMap(n => n + 10, [0, 0], [2, 2]); // [[10, 11, 2], [13, 14, 5]]

If both startIndices and endIndices are omitted, the result is the same as the nestedMap method performed in place.

Parameters

Name Type Description
array NDArray<T> The original array.
callbackfn (value: T, index: number[], array: NDArray<T>, parent: NDArray<T>) => T A function that accepts up to 4 arguments. The nestedFillMap method calls the callbackfn function one time for each element in the array.
startIndices? number[] The coordinates to start filling the array at (inclusive). If a certain start index is negative, the length of that axis of the array will be added to it.
endIndices? number[] The coordinates to stop filling the array at (exclusive). If a certain end index is negative, the length of that axis of the array will be added to it.
thisArg? any An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.

Returns

NDArray<T>

The modified array, which the instance is the same as the original array.


nestedIncludes, nestedIncludesFromLast

array<T>.nestedIncludes(searchElement, fromIndices?): boolean

Determines whether a nested array includes a specified element, searching forwards.

[[0, 1, 2], [3, 4, 5]].nestedIncludes(3); // true
[[0, 1, 2], [3, 4, 5]].nestedIncludes(3, [0, 1]); // false

array<T>.nestedIncludesFromLast(searchElement, fromIndices?): boolean

Determines whether a nested array includes a specified element, searching backwards.

[[0, 1, 2], [3, 4, 5]].nestedIncludesFromLast(2); // true
[[0, 1, 2], [3, 4, 5]].nestedIncludesFromLast(2, [1, 1]); // false

Parameters

Name Type Description
array NDArray<T> The original array.
searchElement T The element to search for.
fromIndices? number[] The coordinates at which to begin searching for (inclusive). If a certain index is negative, the length of that axis of the array will be added to it.

Returns

boolean

true if the element is found in the array, or false otherwise.


nestedIndexOf, nestedLastIndexOf

array<T>.nestedIndexOf(searchElement, fromIndices?): number[] | undefined

Returns the coordinates of the first occurrence of a specified value in an array, or undefined if it is not present.

[[0, 1, 2], [3, 4, 5]].nestedIndexOf(3); // [1, 0]
[[0, 1, 2], [3, 4, 5]].nestedIndexOf(3, [0, 1]); // undefined

array<T>.nestedLastIndexOf(searchElement, fromIndices?): number[] | undefined

Returns the coordinates of the last occurrence of a specified value in an array, or undefined if it is not present.

[[0, 1, 2], [3, 4, 5]].nestedLastIndexOf(2); // [0, 2]
[[0, 1, 2], [3, 4, 5]].nestedLastIndexOf(2, [1, 1]); // undefined

Parameters

Name Type Description
array NDArray<T> The original array.
searchElement T The element to search for.
fromIndices? number[] The coordinates at which to begin searching for (inclusive). If a certain index is negative, the length of that axis of the array will be added to it.

Returns

number[] | undefined

A number array containing the coordinates of the element, or undefined if it is not present.


nestedFind, nestedFindLast

array<T>.nestedFind(predicate, fromIndices?, thisArg?): T | undefined

Returns the value of the first element in a nested array that satisfies the predicate function, or undefined if there is no such element.

[[0, 1, 2], [3, 4, 5]].nestedFind(n => n % 6 == 3); // 3
[[0, 1, 2], [3, 4, 5]].nestedFind(n => n % 6 == 3, [0, 1]); // undefined

array<T>.nestedFindLast(predicate, fromIndices?, thisArg?): T | undefined

Returns the value of the last element in a nested array that satisfies the predicate function, or undefined if there is no such element.

[[0, 1, 2], [3, 4, 5]].nestedFindLast(n => n % 6 == 2); // 2
[[0, 1, 2], [3, 4, 5]].nestedFindLast(n => n % 6 == 2, [1, 1]); // undefined

Parameters

Name Type Description
array NDArray<T> The original array.
predicate (value: T, index: number[], array: NDArray<T>, parent: NDArray<T>) => unknown A function that accepts up to 4 arguments. The nestedFind method calls the predicate function one time for each element in the array until it returns a truthy value.
fromIndices? number[] The coordinates at which to begin searching for (inclusive). If a certain index is negative, the length of that axis of the array will be added to it.
thisArg? any An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.

Returns

T | undefined

The value of the first element in the array that satisfies the predicate function, or undefined if there is no such element.


nestedFindIndex, nestedFindLastIndex

array<T>.nestedFindIndex(predicate, fromIndices?, thisArg?): number[] | undefined

Returns the coordinates of the first element in a nested array that satisfies the predicate function, or undefined if there is no such element.

[[0, 1, 2], [3, 4, 5]].nestedFindIndex(n => n % 6 == 3); // [1, 0]
[[0, 1, 2], [3, 4, 5]].nestedFindIndex(n => n % 6 == 3, [0, 1]); // undefined

array<T>.nestedFindLastIndex(predicate, fromIndices?, thisArg?): number[] | undefined

Returns the coordinates of the last element in a nested array that satisfies the predicate function, or undefined if there is no such element.

[[0, 1, 2], [3, 4, 5]].nestedFindLastIndex(n => n % 6 == 2); // [0, 2]
[[0, 1, 2], [3, 4, 5]].nestedFindLastIndex(n => n % 6 == 2, [1, 1]); // undefined

Parameters

Name Type Description
array NDArray<T> The original array.
predicate (value: T, index: number[], array: NDArray<T>, parent: NDArray<T>) => unknown A function that accepts up to 4 arguments. The nestedFindIndex method calls the predicate function one time for each element in the array until it returns a truthy value.
fromIndices? number[] The coordinates at which to begin searching for (inclusive). If a certain index is negative, the length of that axis of the array will be added to it.
thisArg? any An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.

Returns

number[] | undefined

The coordinates of the first element in the array that satisfies the predicate function, or undefined if there is no such element.


nestedSome, nestedSomeFromLast

array<T>.nestedSome(predicate, fromIndices?, thisArg?): boolean

Determines whether at least one element in a nested array satisfies the predicate function, searching forwards.

[[0, 1, 2], [3, 4, 5]].nestedSome(n => n % 6 == 3); // true
[[0, 1, 2], [3, 4, 5]].nestedSome(n => n % 6 == 3, [0, 1]); // false

array<T>.nestedSomeFromLast(predicate, fromIndices?, thisArg?): boolean

Determines whether at least one element in a nested array satisfies the predicate function, searching backwards.

[[0, 1, 2], [3, 4, 5]].nestedSomeFromLast(n => n % 6 == 2); // true
[[0, 1, 2], [3, 4, 5]].nestedSomeFromLast(n => n % 6 == 2, [1, 1]); // false

Parameters

Name Type Description
array NDArray<T> The original array.
predicate (value: T, index: number[], array: NDArray<T>, parent: NDArray<T>) => unknown A function that accepts up to 4 arguments. The nestedSome method calls the predicate function one time for each element in the array until it returns a truthy value.
fromIndices? number[] The coordinates at which to begin searching for (inclusive). If a certain index is negative, the length of that axis of the array will be added to it.
thisArg? any An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.

Returns

boolean

true if at least one element in the array satisfies the predicate function, or false otherwise.


nestedEvery, nestedEveryFromLast

array<T>.nestedEvery(predicate, fromIndices?, thisArg?): boolean

Determines whether all elements in a nested array satisfies the predicate function, searching forwards.

[[0, 1, 2], [3, 4, 5]].nestedEvery(n => n % 6 != 3); // false
[[0, 1, 2], [3, 4, 5]].nestedEvery(n => n % 6 != 3, [0, 1]); // true

array<T>.nestedEveryFromLast(predicate, fromIndices?, thisArg?): boolean

Determines whether all elements in a nested array satisfies the predicate function, searching backwards.

[[0, 1, 2], [3, 4, 5]].nestedEveryFromLast(n => n % 6 != 2); // false
[[0, 1, 2], [3, 4, 5]].nestedEveryFromLast(n => n % 6 != 2, [1, 1]); // true

Parameters

Name Type Description
array NDArray<T> The original array.
predicate (value: T, index: number[], array: NDArray<T>, parent: NDArray<T>) => unknown A function that accepts up to 4 arguments. The nestedEvery method calls the predicate function one time for each element in the array until it returns a falsy value.
fromIndices? number[] The coordinates at which to begin searching for (inclusive). If a certain index is negative, the length of that axis of the array will be added to it.
thisArg? any An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.

Returns

boolean

true if all elements in the array satisfies the predicate function, or false otherwise.