• Stars
    star
    124
  • Rank 288,207 (Top 6 %)
  • Language
    JavaScript
  • License
    ISC License
  • Created over 6 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Manipulate columnar data efficiently using typed arrays.

@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

# take(values, index) <>

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"]

# taker(index) <>

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"]]

# get(i) <>

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"]

# slice([start[, stop]]) <>

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

# count(values) <>

Returns the number of numeric values in the specified values array.

count([1, "N/A", 2, NaN, 3]) // 3

# counti(values, index) <>

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

# max(values) <>

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

# maxi(values, index) <>

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

# min(values) <>

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

# mini(values, index) <>

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

# mean(values) <>

Returns the arithmetic mean of the specified values array.

mean([0, 1, 4, 8, NaN, 2]) // 3

# meani(values, index) <>

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

# median(values) <>

Returns the median of the specified values array. Equivalent to quantile(values, 0.5).

median([0, 1, 4, 8, NaN, 2]) // 2

# mediani(values, index) <>

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

# quantile(values, p) <>

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

# sum(values) <>

Returns the sum of the specified values array.

sum([0, 1, 4, 8, NaN, 2]) // 15

# sumi(values, index) <>

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

# reverse(values) <>

Returns a reversed copy of the specified values array. Like array.reverse, but returns a copy.

# shuffle(length) <>

Returns an array of integers 0 … length - 1 in random order.

# shufflei(index) <>

Returns a shuffled copy of the specified index array.

Filtering

# filter(values, test) <>

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.

# ascending(a, b) <>

Returns -1 if a is less than b, 1 if a is greater than b, 0 if a is equal to b, or NaN.

# descending(a, b) <>

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

# identity(x) <>

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.

More Repositories

1

plot

A concise API for exploratory data visualization implementing a layered grammar of graphics
HTML
4,253
star
2

framework

A static site generator for data apps, dashboards, reports, and more. Observable Framework combines JavaScript on the front-end for interactive graphics with any language on the back-end for data analysis.
TypeScript
2,355
star
3

runtime

The reactive dataflow runtime that powers Observable Framework and Observable notebooks
JavaScript
991
star
4

stdlib

The Observable standard library.
JavaScript
965
star
5

htl

A tagged template literal that allows safe interpolation of values into HTML, following the HTML5 spec
JavaScript
302
star
6

parser

The Observable parser.
JavaScript
176
star
7

inspector

The Observable standard inspector.
JavaScript
140
star
8

inputs

Better input elements
JavaScript
125
star
9

examples

Examples of using Observable in a variety of contexts
HTML
106
star
10

datasets

Test datasets for convenience in Observable notebooks.
JavaScript
67
star
11

database-proxy

A proxy to connect Observable notebooks to databases on private networks
JavaScript
51
star
12

feedback

Customer submitted bugs and feature requests
42
star
13

vega

Convenience methods for using Vega and Vega-Lite in Observable.
JavaScript
42
star
14

graphviz

A convenience method for using Graphviz.
JavaScript
39
star
15

plot-create-react-app-example

An example of Observable Plot with Create React App
JavaScript
38
star
16

prettier-react-tachyons

A prettier transform for React and Tachyon users.
JavaScript
29
star
17

notebook-download-example

An example of downloading and embedding an Observable notebook into a web app.
JavaScript
23
star
18

react-zoomable-sunburst

create-react-app + observablehq
JavaScript
16
star
19

rollup-plugin-credits

Generate license credits
JavaScript
15
star
20

katex

A minimally-tweaked distribution of KaTeX.
CSS
10
star
21

create

JavaScript
10
star
22

data-loader-examples

A collection of easy to explore and reuse data loader examples in Observable Framework.
JavaScript
9
star
23

framework-runtime

A Docker image optimized to build Framework images
TypeScript
9
star
24

sample-datasets

Sample datasets
8
star
25

plot-cheatsheets

An interactive reference + PDF for learning Observable Plot
7
star
26

documentation

7
star
27

odsc-visualization

Code for talk at ODSC East 2024
JavaScript
7
star
28

observable-jupyter

This repository has been archived. Please see the fork maintained by Thomas Ballinger.
Jupyter Notebook
4
star
29

framework-codespace

A GitHub Codespaces template for Observable Framework
JavaScript
3
star
30

.github

Default community health files for Observable's open-source projects
2
star
31

codemirror-testing

A repo to test out CodeMirror outside of our infrastructure
TypeScript
1
star