Skip to content

Commit

Permalink
flatRollup (#197)
Browse files Browse the repository at this point in the history
* lexicographic order

* flatGroup, flatRollup

* flatGroupSort

* exports

* remove flatGroupSort, lexicographic

Co-authored-by: Mike Bostock <mbostock@gmail.com>
  • Loading branch information
Fil and mbostock committed Jun 5, 2021
1 parent 97aaf56 commit 0c4b2c9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 4 deletions.
8 changes: 8 additions & 0 deletions README.md
Expand Up @@ -417,6 +417,10 @@ This produces:

Equivalent to [group](#group), but returns nested arrays instead of nested maps.

<a name="flatGroup" href="#flatGroup">#</a> d3.<b>flatGroup</b>(<i>iterable</i>, <i>...keys</i>) · [Source](https://github.com/d3/d3-array/blob/master/src/group.js), [Examples](https://observablehq.com/@d3/d3-flatgroup)

Equivalent to [group](#group), but returns the result as a flat array of [key0, key1, …, values] instead of nested maps.

<a name="index" href="#index">#</a> d3.<b>index</b>(<i>iterable</i>, <i>...keys</i>) · [Source](https://github.com/d3/d3-array/blob/master/src/group.js), [Examples](https://observablehq.com/@d3/d3-group)

Equivalent to [group](#group) but returns a unique value per compound key instead of an array, throwing if the key is not unique.
Expand Down Expand Up @@ -507,6 +511,10 @@ To convert a Map to an Array, use [Array.from](https://developer.mozilla.org/en-

Equivalent to [rollup](#rollup), but returns nested arrays instead of nested maps.

<a name="flatRollup" href="#flatRollup">#</a> d3.<b>flatRollup</b>(<i>iterable</i>, <i>...keys</i>) · [Source](https://github.com/d3/d3-array/blob/master/src/group.js), [Examples](https://observablehq.com/@d3/d3-flatgroup)

Equivalent to [rollup](#rollup), but returns the result as a flat array of [key0, key1, …, reduced value] instead of nested maps.

<a name="groupSort" href="#groupSort">#</a> d3.<b>groupSort</b>(<i>iterable</i>, <i>comparator</i>, <i>key</i>) · [Source](https://github.com/d3/d3-array/blob/master/src/groupSort.js), [Examples](https://observablehq.com/@d3/d3-groupsort)
<br><a name="groupSort" href="#groupSort">#</a> d3.<b>groupSort</b>(<i>iterable</i>, <i>accessor</i>, <i>key</i>)

Expand Down
11 changes: 9 additions & 2 deletions src/group.js
Expand Up @@ -9,14 +9,21 @@ export function groups(values, ...keys) {
return nest(values, Array.from, identity, keys);
}

export function flatGroup(values, ...keys) {
let groups = groups(values, ...keys);
function flatten(groups, keys) {
for (let i = 1, n = keys.length; i < n; ++i) {
groups = groups.flatMap(g => g.pop().map(([key, value]) => [...g, key, value]));
}
return groups;
}

export function flatGroup(values, ...keys) {
return flatten(groups(values, ...keys), keys);
}

export function flatRollup(values, reduce, ...keys) {
return flatten(rollups(values, reduce, ...keys), keys);
}

export function rollup(values, reduce, ...keys) {
return nest(values, identity, reduce, keys);
}
Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Expand Up @@ -8,7 +8,7 @@ export {default as descending} from "./descending.js";
export {default as deviation} from "./deviation.js";
export {default as extent} from "./extent.js";
export {Adder, fsum, fcumsum} from "./fsum.js";
export {default as group, groups, index, indexes, rollup, rollups} from "./group.js";
export {default as group, flatGroup, flatRollup, groups, index, indexes, rollup, rollups} from "./group.js";
export {default as groupSort} from "./groupSort.js";
export {default as bin, default as histogram} from "./bin.js"; // Deprecated; use bin.
export {default as thresholdFreedmanDiaconis} from "./threshold/freedmanDiaconis.js";
Expand Down
37 changes: 36 additions & 1 deletion test/group-test.js
@@ -1,5 +1,5 @@
import assert from "assert";
import {group} from "../src/index.js";
import {group, flatGroup, flatRollup} from "../src/index.js";

const data = [
{name: "jim", amount: "34.0", date: "11/12/2015"},
Expand Down Expand Up @@ -129,6 +129,41 @@ it("group(data, accessor) interns keys", () => {
assert.strictEqual([...map.keys()][1], b);
});

it("flatGroup(data, accessor, accessor) returns the expected array", () => {
assert.deepStrictEqual(
flatGroup(data, d => d.name, d => d.amount),
[
['jim', '34.0', [{name: 'jim', amount: '34.0', date: '11/12/2015'}]],
['carl', '120.11', [{name: 'carl', amount: '120.11', date: '11/12/2015'}]],
['stacy', '12.01', [{name: 'stacy', amount: '12.01', date: '01/04/2016'}]],
['stacy', '34.05', [{name: 'stacy', amount: '34.05', date: '01/04/2016'}]]
]
);
});

it("flatRollup(data, reduce, accessor) returns the expected array", () => {
assert.deepStrictEqual(
flatRollup(data, v => v.length, d => d.name),
[
['jim', 1],
['carl', 1],
['stacy', 2]
]
);
});

it("flatRollup(data, reduce, accessor, accessor) returns the expected array", () => {
assert.deepStrictEqual(
flatRollup(data, v => v.length, d => d.name, d => d.amount),
[
['jim', '34.0', 1],
['carl', '120.11', 1],
['stacy', '12.01', 1],
['stacy', '34.05', 1]
]
);
});

function entries(map, depth) {
if (depth > 0) {
return Array.from(map, ([k, v]) => [k, entries(v, depth - 1)]);
Expand Down

0 comments on commit 0c4b2c9

Please sign in to comment.