Skip to content

Commit

Permalink
flatGroup, flatRollup (#196)
Browse files Browse the repository at this point in the history
* flatGroup

* flatRollup (#197)

* lexicographic order

* flatGroup, flatRollup

* flatGroupSort

* exports

* remove flatGroupSort, lexicographic

Co-authored-by: Mike Bostock <mbostock@gmail.com>

* extract tests

* Update README

Co-authored-by: Philippe Rivière <fil@rezo.net>
  • Loading branch information
mbostock and Fil committed Jun 5, 2021
1 parent 3f270df commit 2e41a82
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 1 deletion.
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 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 a flat array of [*key0*, *key1*, …, *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
15 changes: 15 additions & 0 deletions src/group.js
Expand Up @@ -9,6 +9,21 @@ export function groups(values, ...keys) {
return nest(values, Array.from, identity, 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
21 changes: 21 additions & 0 deletions test/flatGroup-test.js
@@ -0,0 +1,21 @@
import assert from "assert";
import {flatGroup} from "../src/index.js";

const data = [
{name: "jim", amount: "34.0", date: "11/12/2015"},
{name: "carl", amount: "120.11", date: "11/12/2015"},
{name: "stacy", amount: "12.01", date: "01/04/2016"},
{name: "stacy", amount: "34.05", date: "01/04/2016"}
];

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'}]]
]
);
});
32 changes: 32 additions & 0 deletions test/flatRollup-test.js
@@ -0,0 +1,32 @@
import assert from "assert";
import {flatRollup} from "../src/index.js";

const data = [
{name: "jim", amount: "34.0", date: "11/12/2015"},
{name: "carl", amount: "120.11", date: "11/12/2015"},
{name: "stacy", amount: "12.01", date: "01/04/2016"},
{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]
]
);
});

0 comments on commit 2e41a82

Please sign in to comment.