Skip to content

Commit 48f48a6

Browse files
committed
90% completion of the list documentation
1 parent f0b8b18 commit 48f48a6

5 files changed

Lines changed: 413 additions & 20 deletions

File tree

docs/docs/code-views/data-array.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: Data Arrays
3+
sidebar_label: Data Arrays
4+
sidebar_position: 500
5+
---
6+
7+
To make common data manipuation operations simple, datacore provides the `DataArray` abstraction, which is a [proxied](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) wrapper around a regular list with a large set of additional functions.
8+
9+
## Creation
10+
11+
Data arrays are mainly present in two places.
12+
13+
### Via `dc.useArray`
14+
15+
The most common route for using data arrays is the `dc.useArray` hook, which takes in a regular array
16+
of data, converts it to a data array, performs operations on it, and then converts it back to a regular array:
17+
18+
```js
19+
return function View() {
20+
// Start with some data you want to process...
21+
const books = dc.useQuery("#books and @page");
22+
// Use `dc.useArray` to get a data array for processing.
23+
const groupedBooks = dc.useArray(books, array =>
24+
array.sort(book => book.$name)
25+
.groupBy(book => book.value("genre")));
26+
27+
// Then render it.
28+
return <dc.List rows={groupedBooks} />;
29+
}
30+
```
31+
32+
### Via `dc.array`
33+
34+
You can also directly make `DataArray`s via the utility function `dc.array(data)`, which accepts a
35+
regular array as input and produces a data array.
36+
37+
```js
38+
return function View() {
39+
// da is a `DataArray`.
40+
const da = dc.array([1, 2, 3]);
41+
// da2 is still a `DataArray`.
42+
const da2 = da.map(x => x + 4).limit(2);
43+
44+
// To get a regular array back, use `.array()`.
45+
const data = da2.array();
46+
}
47+
```
48+
49+
## Indexing and Swizzling
50+
51+
Data arrays support regular indexing just like normal arrays (like `array[0]`), but importantly, they also support
52+
query-language-style "swizzling": if you index into a data array with a field name (like `array.field`), it
53+
automatically maps every element in the array to `field`, flattening `field` if it itself is also an array.
54+
55+
```js
56+
const data = dc.array(dc.query("#books and @page"));
57+
58+
data.$name // => List of all book names.
59+
data.$ctime // => List of all book created times.
60+
```
61+
62+
## Raw Interface
63+
64+
The full interface for the data array implementation is provided below for reference:
65+
66+
```ts
67+
/** A function which maps an array element to some value. */
68+
export type ArrayFunc<T, O> = (elem: T, index: number, arr: T[]) => O;
69+
70+
/** A function which compares two types. */
71+
export type ArrayComparator<T> = (a: T, b: T) => number;
72+
73+
/**
74+
* Proxied interface which allows manipulating array-based data. All functions on a data array produce a NEW array
75+
* (i.e., the arrays are immutable).
76+
*/
77+
export interface DataArray<T> {
78+
/** The total number of elements in the array. */
79+
length: number;
80+
81+
/** Filter the data array down to just elements which match the given predicate. */
82+
where(predicate: ArrayFunc<T, boolean>): DataArray<T>;
83+
/** Alias for 'where' for people who want array semantics. */
84+
filter(predicate: ArrayFunc<T, boolean>): DataArray<T>;
85+
86+
/** Map elements in the data array by applying a function to each. */
87+
map<U>(f: ArrayFunc<T, U>): DataArray<U>;
88+
/** Map elements in the data array by applying a function to each, then flatten the results to produce a new array. */
89+
flatMap<U>(f: ArrayFunc<T, U[]>): DataArray<U>;
90+
/** Mutably change each value in the array, returning the same array which you can further chain off of. */
91+
mutate(f: ArrayFunc<T, any>): DataArray<any>;
92+
93+
/** Limit the total number of entries in the array to the given value. */
94+
limit(count: number): DataArray<T>;
95+
/**
96+
* Take a slice of the array. If `start` is undefined, it is assumed to be 0; if `end` is undefined, it is assumed
97+
* to be the end of the array.
98+
*/
99+
slice(start?: number, end?: number): DataArray<T>;
100+
/** Concatenate the values in this data array with those of another iterable / data array / array. */
101+
concat(other: Iterable<T>): DataArray<T>;
102+
103+
/** Return the first index of the given (optionally starting the search) */
104+
indexOf(element: T, fromIndex?: number): number;
105+
/** Return the first element that satisfies the given predicate. */
106+
find(pred: ArrayFunc<T, boolean>): T | undefined;
107+
/** Find the index of the first element that satisfies the given predicate. Returns -1 if nothing was found. */
108+
findIndex(pred: ArrayFunc<T, boolean>, fromIndex?: number): number;
109+
/** Returns true if the array contains the given element, and false otherwise. */
110+
includes(element: T): boolean;
111+
112+
/**
113+
* Return a string obtained by converting each element in the array to a string, and joining it with the
114+
* given separator (which defaults to ', ').
115+
*/
116+
join(sep?: string): string;
117+
118+
/**
119+
* Return a sorted array sorted by the given key; an optional comparator can be provided, which will
120+
* be used to compare the keys in leiu of the default dataview comparator.
121+
*/
122+
sort<U>(key: ArrayFunc<T, U>, direction?: "asc" | "desc", comparator?: ArrayComparator<U>): DataArray<T>;
123+
124+
/**
125+
* Return an array where elements are grouped by the given key; the resulting array will have objects of the form
126+
* { key: <key value>, rows: DataArray }.
127+
*/
128+
groupBy<U>(key: ArrayFunc<T, U>, comparator?: ArrayComparator<U>): DataArray<{ key: U; rows: DataArray<T> }>;
129+
130+
/**
131+
* Return distinct entries. If a key is provided, then rows with distinct keys are returned.
132+
*/
133+
distinct<U>(key?: ArrayFunc<T, U>, comparator?: ArrayComparator<U>): DataArray<T>;
134+
135+
/** Return true if the predicate is true for all values. */
136+
every(f: ArrayFunc<T, boolean>): boolean;
137+
/** Return true if the predicate is true for at least one value. */
138+
some(f: ArrayFunc<T, boolean>): boolean;
139+
/** Return true if the predicate is FALSE for all values. */
140+
none(f: ArrayFunc<T, boolean>): boolean;
141+
142+
/** Return the first element in the data array. Returns undefined if the array is empty. */
143+
first(): T;
144+
/** Return the last element in the data array. Returns undefined if the array is empty. */
145+
last(): T;
146+
147+
/** Map every element in this data array to the given key, and then flatten it.*/
148+
to(key: string): DataArray<any>;
149+
/**
150+
* Recursively expand the given key, flattening a tree structure based on the key into a flat array. Useful for handling
151+
* hierarchical data like tasks with 'subtasks'.
152+
*/
153+
expand(key: string): DataArray<any>;
154+
155+
/** Run a lambda on each element in the array. */
156+
forEach(f: ArrayFunc<T, void>): void;
157+
158+
/** Convert this to a plain javascript array. */
159+
array(): T[];
160+
161+
/** Allow iterating directly over the array. */
162+
[Symbol.iterator](): Iterator<T>;
163+
164+
/** Map indexes to values. */
165+
[index: number]: any;
166+
/** Automatic flattening of fields. Equivalent to implicitly calling `array.to("field")` */
167+
[field: string]: any;
168+
}
169+
```

0 commit comments

Comments
 (0)