@observablehq/array
This library provides methods for operating on columnar data represented as parallel arrays. Most operations involve computing an index—an array of integers, each in [0, length - 1]—and then using the index to derive new columns.
https://beta.observablehq.com/@mbostock/manipulating-flat-arrays
Installing
Via npm:
npm install @observablehq/array
Via import from unpkg:
<script type="module">
import {take} from "https://unpkg.com/@observablehq/array?module";
</script>
Via script tag from unpkg:
<script src="https://unpkg.com/@observablehq/array"></script>
API Reference
Taking
Returns a new array of values from the specified values array according to the specified index array. The returned array is the same type as the specified values array.
take(["a", "b", "c", "d", "e", "f"], [0, 2, 0, 1]) // ["a", "c", "a", "b"]
Returns a take-like function that, when passed an array of values, returns a new array of values from the specified values array according to the specified index array. The returned array is the same type as the specified values array.
taker([0, 2, 0, 1])(["a", "b", "c", "d", "e", "f"]) // ["a", "c", "a", "b"]
This method is often used to take multiple arrays simultaneously using array.map.
letter = ["a", "b", "c", "d", "e", "f", "g"]
name = ["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"]
[letter, name].map(taker([2, 1, 0])) // [["c", "b", "a"], ["Cee", "Bee", "Ay"]]
Returns a take-like function that, when passed an array of values, returns the value from the specified values array with the specified index i.
get(2)(["a", "b", "c", "d", "e", "f"]) // "c"
This method is often used to get from multiple arrays simultaneously using array.map.
letter = ["a", "b", "c", "d", "e", "f", "g"]
name = ["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"]
[letter, name].map(get(2)) // ["c", "Cee"]
Returns a function that when passed an array, returns a slice of the array according to the specified start and stop index. The returned function is equivalent to calling array.slice.
slice(0, 3)(["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"]) // ["Ay", "Bee", "Cee"]
This method is often used to take multiple arrays simultaneously using array.map.
letter = ["a", "b", "c", "d", "e", "f", "g"]
name = ["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"]
[letter, name].map(slice(0, 3)) // [["a", "b", "c"], ["Ay", "Bee", "Cee"]]
Summarizing
Returns the number of numeric values in the specified values array.
count([1, "N/A", 2, NaN, 3]) // 3
Returns the number of numeric values in the subset of the specified values array in the specified index array. Equivalent to count(take(values, index)).
counti([1, "N/A", 2, NaN, 3], [0, 1, 2]) // 2
Returns the maximum numeric value in the specified values array. For the corresponding index, see top.
max([1, "N/A", 2, NaN, 4.5]) // 4.5
Returns the maximum numeric value in the subset of the specified values array in the specified index array. Equivalent to max(take(values, index)). For the corresponding index, see topi.
maxi([1, "N/A", 2.5, NaN, 4], [0, 1, 2]) // 2
Returns the minimum numeric value in the specified values array. For the corresponding index, see bottom.
min([1, "N/A", 2, NaN, 4.5]) // 1
Returns the minimum numeric value in the subset of the specified values array in the specified index array. Equivalent to min(take(values, index)).For the corresponding index, see bottomi.
mini([1.5, "N/A", 2, NaN, 4], [0, 1, 2]) // 1.5
Returns the arithmetic mean of the specified values array.
mean([0, 1, 4, 8, NaN, 2]) // 3
Returns the arithmetic mean of the subset of the specified values array in the specified index array. Equivalent to mean(take(values, index)).
meani([NaN, 1, 3, 8, 3], [0, 1, 2, 3]) // 4
Returns the median of the specified values array. Equivalent to quantile(values, 0.5).
median([0, 1, 4, 8, NaN, 2]) // 2
Returns the median of the subset of the specified values array in the specified index array. Equivalent to quantile(take(values, index), 0.5).
mediani([0, 1, 4, 8, NaN, 2], [0, 1, 2, 3]) // 2.5
Returns the p-quantile of the specified values array with the specified p using the R-7 method.
quantile([0, 1, 4, 8, NaN, 2], 0.5) // 2
# quantilei(values, index, p) <>
Returns the p-quantile of the subset of the specified values array in the specified index array with the specified p using the R-7 method. Equivalent to quantile(take(values, index), p).
quantilei([0, 1, 4, 8, NaN, 2], [0, 1, 2, 3], 0.5) // 2
Returns the sum of the specified values array.
sum([0, 1, 4, 8, NaN, 2]) // 15
Returns the sum of the subset of the specified values array in the specified index array. Equivalent to sum(take(values, index)).
sumi([0, 1, 4, 8, NaN, 2], [0, 1, 2, 3]) // 13
Sorting
# bottom(values, order = ascending) <>
Returns the index of the specified values array with the corresponding least value according to the specified order comparator.
bottom(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"]) // 7
# bottomi(values, index, order = ascending) <>
Returns the index in the specified index array with the corresponding least value in the specified values array according to the specified order comparator.
bottomi(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"], [0, 2, 4, 6]) // 2
# bottoms(values, k = 5, order = ascending) <>
Returns an array of the k indexes of the specified values array with the corresponding least values according to the specified order comparator.
bottoms(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"], 3) // [7, 8, 5]
# bottomsi(values, index, k = 5, order = ascending) <>
Returns an array of the k indexes in the specified index array with the corresponding least values in the specified values array according to the specified order comparator.
bottomsi(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"], [0, 2, 4, 6], 2) // [2, 0]
# sort(values, order = ascending) <>
Returns the indexes of the specified values array sorted according to the specified order comparator and array of values.
sort(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"]) // [7, 8, 5, 2, 1, 0, 4, 6, 3, 9]
# sorti(values, index, order = ascending) <>
Returns a copy of the specified index array sorted according to the specified order comparator and array of values.
sorti(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"], [0, 2, 4, 6]) // [2, 0, 4, 6]
# top(values, order = ascending) <>
Returns the index of the specified values array with the corresponding greatest value according to the specified order comparator.
top(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"]) // 9
# topi(values, index, order = ascending) <>
Returns the index in the specified index array with the corresponding greatest value in the specified values array according to the specified order comparator.
topi(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"], [0, 2, 4, 6]) // 6
# tops(values, k = 5, order = ascending) <>
Returns an array of the k indexes of the specified values array with the corresponding greatest values according to the specified order comparator.
tops(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"], 3) // [9, 3, 6]
# topsi(values, index, k = 5, order = ascending) <>
Returns an array of the k indexes in the specified index array with the corresponding greatest values in the specified values array according to the specified order comparator.
topsi(["f", "e", "d", "i", "g", "c", "h", "a", "b", "j"], [0, 2, 4, 6], 2) // [6, 4]
Arranging
Returns a reversed copy of the specified values array. Like array.reverse, but returns a copy.
Returns an array of integers 0 … length - 1 in random order.
Returns a shuffled copy of the specified index array.
Filtering
Returns an array of indexes from the specified values array for which the specified test function returned truthy. The test function is passed a value from the values array, the corresponding index, and the values array itself.
filter(["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"], d => d.length === 2) // [0, 4, 5]
# filteri(values, index, test) <>
Returns the subset of the specified index for which the specified test function returned truthy. The test function is passed a value from the values array, the corresponding index, and the values array itself.
filteri(["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"], [0, 1, 2, 3], d => d.length === 2) // [0]
Grouping
# group(values, key = identity[, value]) <>
Returns a new Map where the keys of the map are computed by applying the specified key function to each element in the specified values array.
name = ["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"]
group(name, d => d.length) // {2 => ["Ay", "Ee", "Ef"], 3 => ["Bee", "Cee", "Dee", "Gee"]}
If a value function is specified, it is invoked with the array of indexes for each entry in the returned map, and the returned map’s value is replaced by whatever the value function returns.
letter = ["a", "b", "c", "d", "e", "f", "g"]
group(name, d => d.length, i => take(letter, i)) // {2 => ["a", "e", "f"], 3 => ["b", "c", "d", "g"]}
group(name, d => d.length, i => i.length) // {2 => 3, 3 => 4}
# groupi(values, index, key = identity[, value]) <>
Returns a new Map where the keys of the map are computed by applying the specified key function to each element in the specified values array present in the specified index array.
name = ["Ay", "Bee", "Cee", "Dee", "Ee", "Ef", "Gee"]
groupi(name, [0, 1, 2], d => d.length) // {2 => ["Ay"], 3 => ["Bee", "Cee"]}
If a value function is specified, it is invoked with the array of indexes for each entry in the returned map, and the returned map’s value is replaced by whatever the value function returns.
letter = ["a", "b", "c", "d", "e", "f", "g"]
groupi(name, [0, 1, 2], d => d.length, i => take(letter, i)) // {2 => ["a"], 3 => ["b", "c"]}
groupi(name, [0, 1, 2], d => d.length, i => i.length) // {2 => 1, 3 => 2}
Comparing
These functions are useful as the order argument to sort, top and bottom.
Returns -1 if a is less than b, 1 if a is greater than b, 0 if a is equal to b, or NaN.
Returns -1 if b is less than a, 1 if b is greater than a, 0 if b is equal to a, or NaN.
Other
Returns x.
# range([start, ]stop[, step]]) <>
Returns an array of integers starting at the specified inclusive start value and stopping before the specified exclusive stop value. If a start value is not specified, it defaults to zero; if a step value is not specified, it defaults to 1.