@tidyjs/tidy 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/addRows.js.map +1 -1
- package/dist/es/arrange.js +9 -5
- package/dist/es/arrange.js.map +1 -1
- package/dist/es/complete.js.map +1 -1
- package/dist/es/count.js +6 -2
- package/dist/es/count.js.map +1 -1
- package/dist/es/debug.js +4 -2
- package/dist/es/debug.js.map +1 -1
- package/dist/es/distinct.js +3 -3
- package/dist/es/distinct.js.map +1 -1
- package/dist/es/expand.js +18 -13
- package/dist/es/expand.js.map +1 -1
- package/dist/es/fill.js +10 -3
- package/dist/es/fill.js.map +1 -1
- package/dist/es/filter.js.map +1 -1
- package/dist/es/fullJoin.js +23 -20
- package/dist/es/fullJoin.js.map +1 -1
- package/dist/es/groupBy.js +56 -28
- package/dist/es/groupBy.js.map +1 -1
- package/dist/es/helpers/assignGroupKeys.js +4 -4
- package/dist/es/helpers/assignGroupKeys.js.map +1 -1
- package/dist/es/helpers/groupMap.js +2 -2
- package/dist/es/helpers/groupMap.js.map +1 -1
- package/dist/es/helpers/groupTraversal.js +5 -4
- package/dist/es/helpers/groupTraversal.js.map +1 -1
- package/dist/es/helpers/identity.js.map +1 -1
- package/dist/es/helpers/isObject.js.map +1 -1
- package/dist/es/helpers/keysFromItems.js +1 -2
- package/dist/es/helpers/keysFromItems.js.map +1 -1
- package/dist/es/helpers/singleOrArray.js.map +1 -1
- package/dist/es/helpers/summation.js +11 -3
- package/dist/es/helpers/summation.js.map +1 -1
- package/dist/es/innerJoin.js +37 -12
- package/dist/es/innerJoin.js.map +1 -1
- package/dist/es/item/rate.js +2 -3
- package/dist/es/item/rate.js.map +1 -1
- package/dist/es/leftJoin.js +13 -8
- package/dist/es/leftJoin.js.map +1 -1
- package/dist/es/map.js.map +1 -1
- package/dist/es/math/math.js.map +1 -1
- package/dist/es/mutate.js +1 -1
- package/dist/es/mutate.js.map +1 -1
- package/dist/es/mutateWithSummary.js +1 -1
- package/dist/es/mutateWithSummary.js.map +1 -1
- package/dist/es/pivotLonger.js +31 -7
- package/dist/es/pivotLonger.js.map +1 -1
- package/dist/es/pivotWider.js +24 -19
- package/dist/es/pivotWider.js.map +1 -1
- package/dist/es/rename.js.map +1 -1
- package/dist/es/replaceNully.js +1 -1
- package/dist/es/replaceNully.js.map +1 -1
- package/dist/es/select.js +3 -3
- package/dist/es/select.js.map +1 -1
- package/dist/es/selectors/contains.js.map +1 -1
- package/dist/es/selectors/endsWith.js.map +1 -1
- package/dist/es/selectors/everything.js.map +1 -1
- package/dist/es/selectors/matches.js.map +1 -1
- package/dist/es/selectors/negate.js +2 -2
- package/dist/es/selectors/negate.js.map +1 -1
- package/dist/es/selectors/numRange.js.map +1 -1
- package/dist/es/selectors/startsWith.js.map +1 -1
- package/dist/es/sequences/fullSeq.js +5 -1
- package/dist/es/sequences/fullSeq.js.map +1 -1
- package/dist/es/slice.js +2 -3
- package/dist/es/slice.js.map +1 -1
- package/dist/es/summarize.js +6 -4
- package/dist/es/summarize.js.map +1 -1
- package/dist/es/summary/deviation.js.map +1 -1
- package/dist/es/summary/first.js.map +1 -1
- package/dist/es/summary/last.js.map +1 -1
- package/dist/es/summary/max.js.map +1 -1
- package/dist/es/summary/mean.js.map +1 -1
- package/dist/es/summary/meanRate.js.map +1 -1
- package/dist/es/summary/median.js.map +1 -1
- package/dist/es/summary/min.js.map +1 -1
- package/dist/es/summary/n.js.map +1 -1
- package/dist/es/summary/nDistinct.js +2 -2
- package/dist/es/summary/nDistinct.js.map +1 -1
- package/dist/es/summary/sum.js.map +1 -1
- package/dist/es/summary/variance.js.map +1 -1
- package/dist/es/tally.js +4 -2
- package/dist/es/tally.js.map +1 -1
- package/dist/es/tidy.js.map +1 -1
- package/dist/es/total.js.map +1 -1
- package/dist/es/transmute.js.map +1 -1
- package/dist/es/vector/cumsum.js.map +1 -1
- package/dist/es/vector/lag.js +1 -1
- package/dist/es/vector/lag.js.map +1 -1
- package/dist/es/vector/lead.js +1 -1
- package/dist/es/vector/lead.js.map +1 -1
- package/dist/es/vector/roll.js +1 -1
- package/dist/es/vector/roll.js.map +1 -1
- package/dist/es/vector/rowNumber.js.map +1 -1
- package/dist/es/when.js +1 -2
- package/dist/es/when.js.map +1 -1
- package/dist/lib/addRows.js +0 -2
- package/dist/lib/addRows.js.map +1 -1
- package/dist/lib/arrange.js +9 -7
- package/dist/lib/arrange.js.map +1 -1
- package/dist/lib/complete.js +0 -2
- package/dist/lib/complete.js.map +1 -1
- package/dist/lib/count.js +6 -4
- package/dist/lib/count.js.map +1 -1
- package/dist/lib/debug.js +4 -4
- package/dist/lib/debug.js.map +1 -1
- package/dist/lib/distinct.js +3 -5
- package/dist/lib/distinct.js.map +1 -1
- package/dist/lib/expand.js +18 -15
- package/dist/lib/expand.js.map +1 -1
- package/dist/lib/fill.js +10 -5
- package/dist/lib/fill.js.map +1 -1
- package/dist/lib/filter.js +0 -2
- package/dist/lib/filter.js.map +1 -1
- package/dist/lib/fullJoin.js +22 -21
- package/dist/lib/fullJoin.js.map +1 -1
- package/dist/lib/groupBy.js +56 -30
- package/dist/lib/groupBy.js.map +1 -1
- package/dist/lib/helpers/assignGroupKeys.js +4 -6
- package/dist/lib/helpers/assignGroupKeys.js.map +1 -1
- package/dist/lib/helpers/groupMap.js +2 -4
- package/dist/lib/helpers/groupMap.js.map +1 -1
- package/dist/lib/helpers/groupTraversal.js +5 -6
- package/dist/lib/helpers/groupTraversal.js.map +1 -1
- package/dist/lib/helpers/identity.js +0 -2
- package/dist/lib/helpers/identity.js.map +1 -1
- package/dist/lib/helpers/isObject.js +0 -2
- package/dist/lib/helpers/isObject.js.map +1 -1
- package/dist/lib/helpers/keysFromItems.js +1 -4
- package/dist/lib/helpers/keysFromItems.js.map +1 -1
- package/dist/lib/helpers/singleOrArray.js +0 -2
- package/dist/lib/helpers/singleOrArray.js.map +1 -1
- package/dist/lib/helpers/summation.js +10 -4
- package/dist/lib/helpers/summation.js.map +1 -1
- package/dist/lib/index.js +0 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/innerJoin.js +38 -14
- package/dist/lib/innerJoin.js.map +1 -1
- package/dist/lib/item/rate.js +2 -5
- package/dist/lib/item/rate.js.map +1 -1
- package/dist/lib/leftJoin.js +12 -9
- package/dist/lib/leftJoin.js.map +1 -1
- package/dist/lib/map.js +0 -2
- package/dist/lib/map.js.map +1 -1
- package/dist/lib/math/math.js +0 -2
- package/dist/lib/math/math.js.map +1 -1
- package/dist/lib/mutate.js +1 -3
- package/dist/lib/mutate.js.map +1 -1
- package/dist/lib/mutateWithSummary.js +1 -3
- package/dist/lib/mutateWithSummary.js.map +1 -1
- package/dist/lib/pivotLonger.js +31 -9
- package/dist/lib/pivotLonger.js.map +1 -1
- package/dist/lib/pivotWider.js +24 -21
- package/dist/lib/pivotWider.js.map +1 -1
- package/dist/lib/rename.js +0 -2
- package/dist/lib/rename.js.map +1 -1
- package/dist/lib/replaceNully.js +1 -3
- package/dist/lib/replaceNully.js.map +1 -1
- package/dist/lib/select.js +3 -5
- package/dist/lib/select.js.map +1 -1
- package/dist/lib/selectors/contains.js +0 -2
- package/dist/lib/selectors/contains.js.map +1 -1
- package/dist/lib/selectors/endsWith.js +0 -2
- package/dist/lib/selectors/endsWith.js.map +1 -1
- package/dist/lib/selectors/everything.js +0 -2
- package/dist/lib/selectors/everything.js.map +1 -1
- package/dist/lib/selectors/matches.js +0 -2
- package/dist/lib/selectors/matches.js.map +1 -1
- package/dist/lib/selectors/negate.js +2 -4
- package/dist/lib/selectors/negate.js.map +1 -1
- package/dist/lib/selectors/numRange.js +0 -2
- package/dist/lib/selectors/numRange.js.map +1 -1
- package/dist/lib/selectors/startsWith.js +0 -2
- package/dist/lib/selectors/startsWith.js.map +1 -1
- package/dist/lib/sequences/fullSeq.js +5 -3
- package/dist/lib/sequences/fullSeq.js.map +1 -1
- package/dist/lib/slice.js +2 -5
- package/dist/lib/slice.js.map +1 -1
- package/dist/lib/summarize.js +6 -6
- package/dist/lib/summarize.js.map +1 -1
- package/dist/lib/summary/deviation.js +0 -2
- package/dist/lib/summary/deviation.js.map +1 -1
- package/dist/lib/summary/first.js +0 -2
- package/dist/lib/summary/first.js.map +1 -1
- package/dist/lib/summary/last.js +0 -2
- package/dist/lib/summary/last.js.map +1 -1
- package/dist/lib/summary/max.js +0 -2
- package/dist/lib/summary/max.js.map +1 -1
- package/dist/lib/summary/mean.js +0 -2
- package/dist/lib/summary/mean.js.map +1 -1
- package/dist/lib/summary/meanRate.js +0 -2
- package/dist/lib/summary/meanRate.js.map +1 -1
- package/dist/lib/summary/median.js +0 -2
- package/dist/lib/summary/median.js.map +1 -1
- package/dist/lib/summary/min.js +0 -2
- package/dist/lib/summary/min.js.map +1 -1
- package/dist/lib/summary/n.js +0 -2
- package/dist/lib/summary/n.js.map +1 -1
- package/dist/lib/summary/nDistinct.js +2 -4
- package/dist/lib/summary/nDistinct.js.map +1 -1
- package/dist/lib/summary/sum.js +0 -2
- package/dist/lib/summary/sum.js.map +1 -1
- package/dist/lib/summary/variance.js +0 -2
- package/dist/lib/summary/variance.js.map +1 -1
- package/dist/lib/tally.js +4 -4
- package/dist/lib/tally.js.map +1 -1
- package/dist/lib/tidy.js +0 -2
- package/dist/lib/tidy.js.map +1 -1
- package/dist/lib/total.js +0 -2
- package/dist/lib/total.js.map +1 -1
- package/dist/lib/transmute.js +0 -2
- package/dist/lib/transmute.js.map +1 -1
- package/dist/lib/vector/cumsum.js +0 -2
- package/dist/lib/vector/cumsum.js.map +1 -1
- package/dist/lib/vector/lag.js +1 -3
- package/dist/lib/vector/lag.js.map +1 -1
- package/dist/lib/vector/lead.js +1 -3
- package/dist/lib/vector/lead.js.map +1 -1
- package/dist/lib/vector/roll.js +1 -3
- package/dist/lib/vector/roll.js.map +1 -1
- package/dist/lib/vector/rowNumber.js +0 -2
- package/dist/lib/vector/rowNumber.js.map +1 -1
- package/dist/lib/when.js +1 -4
- package/dist/lib/when.js.map +1 -1
- package/dist/tidy.d.ts +217 -1775
- package/dist/umd/tidy.js +307 -184
- package/dist/umd/tidy.js.map +1 -1
- package/dist/umd/tidy.min.js +1 -1
- package/dist/umd/tidy.min.js.map +1 -1
- package/package.json +14 -9
- package/LICENSE +0 -21
package/dist/lib/distinct.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distinct.js","sources":["../../src/distinct.ts"],"sourcesContent":["import { KeyOrFn, TidyFn } from './types';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\n\n/**\n * Removes items with duplicate values for the specified keys.\n * If no keys provided, uses strict equality.\n *\n * @param keys Keys to compute distinct across\n */\nexport function distinct<T extends object>(\n keys?: SingleOrArray<KeyOrFn<T>> | null | undefined\n): TidyFn<T> {\n const _distinct: TidyFn<T> = (items: T[]): T[] => {\n keys = singleOrArray(keys);\n\n if (!keys.length) {\n // https://jsperf.com/unique-array-by-strict-equality\n const set = new Set<T>();\n for (const item of items) {\n set.add(item);\n }\n return Array.from(set);\n }\n\n // compare keys\n // https://jsperf.com/distinct-by-key\n // turns out nested Maps are faster than string keys. AND they support\n // and arbitrary value.\n const rootMap = new Map();\n const distinctItems: T[] = [];\n const lastKey = keys[keys.length - 1];\n for (const item of items) {\n let map = rootMap;\n let hasItem = false;\n\n // go through each key to find out if we have it\n for (const key of keys) {\n const mapItemKey =\n typeof key === 'function' ? key(item) : item[key as keyof T];\n // last key, check if we already added it\n if (key === lastKey) {\n hasItem = map.has(mapItemKey);\n if (!hasItem) {\n distinctItems.push(item);\n map.set(mapItemKey, true);\n }\n break;\n }\n\n // create maps all the way down\n if (!map.has(mapItemKey)) {\n map.set(mapItemKey, new Map());\n }\n\n // move to next inner map\n map = map.get(mapItemKey);\n }\n }\n\n return distinctItems;\n };\n\n return _distinct;\n}\n"],"names":["singleOrArray"],"mappings":"
|
|
1
|
+
{"version":3,"file":"distinct.js","sources":["../../src/distinct.ts"],"sourcesContent":["import { KeyOrFn, TidyFn } from './types';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\n\n/**\n * Removes items with duplicate values for the specified keys.\n * If no keys provided, uses strict equality.\n *\n * @param keys Keys to compute distinct across\n */\nexport function distinct<T extends object>(\n keys?: SingleOrArray<KeyOrFn<T>> | null | undefined\n): TidyFn<T> {\n const _distinct: TidyFn<T> = (items: T[]): T[] => {\n keys = singleOrArray(keys);\n\n if (!keys.length) {\n // https://jsperf.com/unique-array-by-strict-equality\n const set = new Set<T>();\n for (const item of items) {\n set.add(item);\n }\n return Array.from(set);\n }\n\n // compare keys\n // https://jsperf.com/distinct-by-key\n // turns out nested Maps are faster than string keys. AND they support\n // and arbitrary value.\n const rootMap = new Map();\n const distinctItems: T[] = [];\n const lastKey = keys[keys.length - 1];\n for (const item of items) {\n let map = rootMap;\n let hasItem = false;\n\n // go through each key to find out if we have it\n for (const key of keys) {\n const mapItemKey =\n typeof key === 'function' ? key(item) : item[key as keyof T];\n // last key, check if we already added it\n if (key === lastKey) {\n hasItem = map.has(mapItemKey);\n if (!hasItem) {\n distinctItems.push(item);\n map.set(mapItemKey, true);\n }\n break;\n }\n\n // create maps all the way down\n if (!map.has(mapItemKey)) {\n map.set(mapItemKey, new Map());\n }\n\n // move to next inner map\n map = map.get(mapItemKey);\n }\n }\n\n return distinctItems;\n };\n\n return _distinct;\n}\n"],"names":["singleOrArray"],"mappings":";;;;AASO,SAAS,SACd,IACW,EAAA;AACX,EAAM,MAAA,SAAA,GAAuB,CAAC,KAAoB,KAAA;AAChD,IAAA,IAAA,GAAOA,4BAAc,IAAI,CAAA,CAAA;AAEzB,IAAI,IAAA,CAAC,KAAK,MAAQ,EAAA;AAEhB,MAAM,MAAA,GAAA,uBAAU,GAAO,EAAA,CAAA;AACvB,MAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,QAAA,GAAA,CAAI,IAAI,IAAI,CAAA,CAAA;AAAA,OACd;AACA,MAAO,OAAA,KAAA,CAAM,KAAK,GAAG,CAAA,CAAA;AAAA,KACvB;AAMA,IAAM,MAAA,OAAA,uBAAc,GAAI,EAAA,CAAA;AACxB,IAAA,MAAM,gBAAqB,EAAC,CAAA;AAC5B,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,IAAK,CAAA,MAAA,GAAS,CAAC,CAAA,CAAA;AACpC,IAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,MAAA,IAAI,GAAM,GAAA,OAAA,CAAA;AACV,MAAA,IAAI,OAAU,GAAA,KAAA,CAAA;AAGd,MAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,QAAM,MAAA,UAAA,GACJ,OAAO,GAAQ,KAAA,UAAA,GAAa,IAAI,IAAI,CAAA,GAAI,KAAK,GAAc,CAAA,CAAA;AAE7D,QAAA,IAAI,QAAQ,OAAS,EAAA;AACnB,UAAU,OAAA,GAAA,GAAA,CAAI,IAAI,UAAU,CAAA,CAAA;AAC5B,UAAA,IAAI,CAAC,OAAS,EAAA;AACZ,YAAA,aAAA,CAAc,KAAK,IAAI,CAAA,CAAA;AACvB,YAAI,GAAA,CAAA,GAAA,CAAI,YAAY,IAAI,CAAA,CAAA;AAAA,WAC1B;AACA,UAAA,MAAA;AAAA,SACF;AAGA,QAAA,IAAI,CAAC,GAAA,CAAI,GAAI,CAAA,UAAU,CAAG,EAAA;AACxB,UAAA,GAAA,CAAI,GAAI,CAAA,UAAA,kBAAgB,IAAA,GAAA,EAAK,CAAA,CAAA;AAAA,SAC/B;AAGA,QAAM,GAAA,GAAA,GAAA,CAAI,IAAI,UAAU,CAAA,CAAA;AAAA,OAC1B;AAAA,KACF;AAEA,IAAO,OAAA,aAAA,CAAA;AAAA,GACT,CAAA;AAEA,EAAO,OAAA,SAAA,CAAA;AACT;;;;"}
|
package/dist/lib/expand.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
function expand(expandKeys) {
|
|
6
4
|
const _expand = (items) => {
|
|
7
5
|
const keyMap = makeKeyMap(expandKeys);
|
|
@@ -16,26 +14,31 @@ function expand(expandKeys) {
|
|
|
16
14
|
} else {
|
|
17
15
|
values = Array.from(new Set(items.map((d) => d[key])));
|
|
18
16
|
}
|
|
19
|
-
vectors.push(values.map((value) => ({[key]: value})));
|
|
17
|
+
vectors.push(values.map((value) => ({ [key]: value })));
|
|
20
18
|
}
|
|
21
19
|
return makeCombinations(vectors);
|
|
22
20
|
};
|
|
23
21
|
return _expand;
|
|
24
22
|
}
|
|
23
|
+
const EXPAND_WARN_THRESHOLD = 1e5;
|
|
25
24
|
function makeCombinations(vectors) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
if (!vectors.length) return [];
|
|
26
|
+
const totalSize = vectors.reduce((acc, v) => acc * v.length, 1);
|
|
27
|
+
if (totalSize > EXPAND_WARN_THRESHOLD) {
|
|
28
|
+
console.warn(
|
|
29
|
+
`tidy expand: generating ${totalSize.toLocaleString()} combinations. This may be slow or use excessive memory.`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
let result = [null];
|
|
33
|
+
for (const vector of vectors) {
|
|
34
|
+
const next = [];
|
|
35
|
+
for (const baseObj of result) {
|
|
36
|
+
for (const item of vector) {
|
|
37
|
+
next.push(baseObj == null ? item : { ...baseObj, ...item });
|
|
38
|
+
}
|
|
35
39
|
}
|
|
40
|
+
result = next;
|
|
36
41
|
}
|
|
37
|
-
const result = [];
|
|
38
|
-
combine(result, null, vectors);
|
|
39
42
|
return result;
|
|
40
43
|
}
|
|
41
44
|
function makeKeyMap(keys) {
|
|
@@ -48,7 +51,7 @@ function makeKeyMap(keys) {
|
|
|
48
51
|
} else if (typeof keys === "object") {
|
|
49
52
|
return keys;
|
|
50
53
|
}
|
|
51
|
-
return {[keys]: keys};
|
|
54
|
+
return { [keys]: keys };
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
exports.expand = expand;
|
package/dist/lib/expand.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expand.js","sources":["../../src/expand.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"expand.js","sources":["../../src/expand.ts"],"sourcesContent":["import { SingleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn } from './types';\nimport { Prettify } from './type-utils';\n\n// helper types\nexport type KeyMap<T extends object = any> = Partial<{\n [key in keyof T]: keyof T | Array<T[key]> | ((items: T[]) => T[key][]);\n}>;\n\n/**\n * Expands a set of items to include all combinations of the specified keys.\n */\n// prettier-ignore\nexport function expand<T extends object = any, K extends keyof T = keyof T>(expandKeys: K): TidyFn<T, Prettify<Pick<T, K>>>;\n// prettier-ignore\nexport function expand<T extends object = any, K extends (keyof T)[] = (keyof T)[]>(expandKeys: K): TidyFn<T, Prettify<Pick<T, K[number]>>>;\n// prettier-ignore\nexport function expand<T extends object = any, K extends KeyMap<T> = KeyMap<T>>(expandKeys: K): TidyFn<T, Pick<T, Extract<keyof K, keyof T>>>\n// prettier-ignore\nexport function expand<T extends object>(expandKeys: SingleOrArray<Key> | KeyMap<T>): TidyFn<T> {\n const _expand: TidyFn<T> = (items: T[]) => {\n const keyMap = makeKeyMap(expandKeys);\n\n // for each key, get all distinct values or use the provided values\n const vectors = [];\n for (const key in keyMap) {\n const keyValue = keyMap[key];\n let values;\n if (typeof keyValue === 'function') {\n values = keyValue(items);\n } else if (Array.isArray(keyValue)) {\n values = keyValue;\n } else {\n // read distinct values from the key in the data\n values = Array.from(new Set(items.map((d) => d[key as keyof T])));\n }\n\n vectors.push(values.map((value: any) => ({ [key]: value })));\n }\n\n // make all combinations of all value sets\n return makeCombinations(vectors);\n };\n\n return _expand;\n}\n\n/*\n Recursively compute key combinations\n*/\nconst EXPAND_WARN_THRESHOLD = 100_000;\n\n/*\n Iteratively compute key combinations (avoids recursive array slicing)\n*/\nfunction makeCombinations(vectors: any[][]): any[] {\n if (!vectors.length) return [];\n\n // warn if Cartesian product will be very large\n const totalSize = vectors.reduce((acc, v) => acc * v.length, 1);\n if (totalSize > EXPAND_WARN_THRESHOLD) {\n console.warn(\n `tidy expand: generating ${totalSize.toLocaleString()} combinations. ` +\n `This may be slow or use excessive memory.`\n );\n }\n\n let result: any[] = [null];\n for (const vector of vectors) {\n const next: any[] = [];\n for (const baseObj of result) {\n for (const item of vector) {\n next.push(baseObj == null ? item : { ...baseObj, ...item });\n }\n }\n result = next;\n }\n return result;\n}\n\n// convert by option in to a map from T key to JoinT key\nexport function makeKeyMap(keys: SingleOrArray<Key> | KeyMap): KeyMap {\n if (Array.isArray(keys)) {\n const keyMap: KeyMap = {};\n for (const key of keys) {\n keyMap[key as any] = key;\n }\n return keyMap;\n } else if (typeof keys === 'object') {\n return keys;\n }\n\n return { [keys]: keys as any } as KeyMap;\n}\n"],"names":[],"mappings":";;AAmBO,SAAS,OAAyB,UAAuD,EAAA;AAC9F,EAAM,MAAA,OAAA,GAAqB,CAAC,KAAe,KAAA;AACzC,IAAM,MAAA,MAAA,GAAS,WAAW,UAAU,CAAA,CAAA;AAGpC,IAAA,MAAM,UAAU,EAAC,CAAA;AACjB,IAAA,KAAA,MAAW,OAAO,MAAQ,EAAA;AACxB,MAAM,MAAA,QAAA,GAAW,OAAO,GAAG,CAAA,CAAA;AAC3B,MAAI,IAAA,MAAA,CAAA;AACJ,MAAI,IAAA,OAAO,aAAa,UAAY,EAAA;AAClC,QAAA,MAAA,GAAS,SAAS,KAAK,CAAA,CAAA;AAAA,OACd,MAAA,IAAA,KAAA,CAAM,OAAQ,CAAA,QAAQ,CAAG,EAAA;AAClC,QAAS,MAAA,GAAA,QAAA,CAAA;AAAA,OACJ,MAAA;AAEL,QAAA,MAAA,GAAS,KAAM,CAAA,IAAA,CAAK,IAAI,GAAA,CAAI,KAAM,CAAA,GAAA,CAAI,CAAC,CAAA,KAAM,CAAE,CAAA,GAAc,CAAC,CAAC,CAAC,CAAA,CAAA;AAAA,OAClE;AAEA,MAAQ,OAAA,CAAA,IAAA,CAAK,MAAO,CAAA,GAAA,CAAI,CAAC,KAAA,MAAgB,EAAE,CAAC,GAAG,GAAG,KAAM,EAAA,CAAE,CAAC,CAAA,CAAA;AAAA,KAC7D;AAGA,IAAA,OAAO,iBAAiB,OAAO,CAAA,CAAA;AAAA,GACjC,CAAA;AAEA,EAAO,OAAA,OAAA,CAAA;AACT,CAAA;AAKA,MAAM,qBAAwB,GAAA,GAAA,CAAA;AAK9B,SAAS,iBAAiB,OAAyB,EAAA;AACjD,EAAA,IAAI,CAAC,OAAA,CAAQ,MAAQ,EAAA,OAAO,EAAC,CAAA;AAG7B,EAAM,MAAA,SAAA,GAAY,QAAQ,MAAO,CAAA,CAAC,KAAK,CAAM,KAAA,GAAA,GAAM,CAAE,CAAA,MAAA,EAAQ,CAAC,CAAA,CAAA;AAC9D,EAAA,IAAI,YAAY,qBAAuB,EAAA;AACrC,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN,CAAA,wBAAA,EAA2B,SAAU,CAAA,cAAA,EAAgB,CAAA,wDAAA,CAAA;AAAA,KAEvD,CAAA;AAAA,GACF;AAEA,EAAI,IAAA,MAAA,GAAgB,CAAC,IAAI,CAAA,CAAA;AACzB,EAAA,KAAA,MAAW,UAAU,OAAS,EAAA;AAC5B,IAAA,MAAM,OAAc,EAAC,CAAA;AACrB,IAAA,KAAA,MAAW,WAAW,MAAQ,EAAA;AAC5B,MAAA,KAAA,MAAW,QAAQ,MAAQ,EAAA;AACzB,QAAK,IAAA,CAAA,IAAA,CAAK,WAAW,IAAO,GAAA,IAAA,GAAO,EAAE,GAAG,OAAA,EAAS,GAAG,IAAA,EAAM,CAAA,CAAA;AAAA,OAC5D;AAAA,KACF;AACA,IAAS,MAAA,GAAA,IAAA,CAAA;AAAA,GACX;AACA,EAAO,OAAA,MAAA,CAAA;AACT,CAAA;AAGO,SAAS,WAAW,IAA2C,EAAA;AACpE,EAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,IAAI,CAAG,EAAA;AACvB,IAAA,MAAM,SAAiB,EAAC,CAAA;AACxB,IAAA,KAAA,MAAW,OAAO,IAAM,EAAA;AACtB,MAAA,MAAA,CAAO,GAAU,CAAI,GAAA,GAAA,CAAA;AAAA,KACvB;AACA,IAAO,OAAA,MAAA,CAAA;AAAA,GACT,MAAA,IAAW,OAAO,IAAA,KAAS,QAAU,EAAA;AACnC,IAAO,OAAA,IAAA,CAAA;AAAA,GACT;AAEA,EAAA,OAAO,EAAE,CAAC,IAAI,GAAG,IAAY,EAAA,CAAA;AAC/B;;;;;"}
|
package/dist/lib/fill.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var singleOrArray = require('./helpers/singleOrArray.js');
|
|
6
4
|
|
|
7
5
|
function fill(keys) {
|
|
@@ -9,11 +7,18 @@ function fill(keys) {
|
|
|
9
7
|
const keysArray = singleOrArray.singleOrArray(keys);
|
|
10
8
|
const replaceMap = {};
|
|
11
9
|
return items.map((d) => {
|
|
12
|
-
|
|
10
|
+
let needsCopy = false;
|
|
13
11
|
for (const key of keysArray) {
|
|
14
|
-
if (
|
|
15
|
-
replaceMap[key] =
|
|
12
|
+
if (d[key] != null) {
|
|
13
|
+
replaceMap[key] = d[key];
|
|
16
14
|
} else if (replaceMap[key] != null) {
|
|
15
|
+
needsCopy = true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (!needsCopy) return d;
|
|
19
|
+
const obj = { ...d };
|
|
20
|
+
for (const key of keysArray) {
|
|
21
|
+
if (obj[key] == null && replaceMap[key] != null) {
|
|
17
22
|
obj[key] = replaceMap[key];
|
|
18
23
|
}
|
|
19
24
|
}
|
package/dist/lib/fill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fill.js","sources":["../../src/fill.ts"],"sourcesContent":["import { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn } from './types';\n\n/**\n * Fills values for the specified keys to match the last seen value in the collection.\n */\nexport function fill<T extends object>(keys: SingleOrArray<Key>): TidyFn<T> {\n const _fill: TidyFn<T> = (items: T[]): T[] => {\n const keysArray = singleOrArray(keys);\n\n const replaceMap: Partial<T> = {};\n\n return items.map((d) => {\n
|
|
1
|
+
{"version":3,"file":"fill.js","sources":["../../src/fill.ts"],"sourcesContent":["import { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Key, TidyFn } from './types';\n\n/**\n * Fills values for the specified keys to match the last seen value in the collection.\n */\nexport function fill<T extends object>(keys: SingleOrArray<Key>): TidyFn<T> {\n const _fill: TidyFn<T> = (items: T[]): T[] => {\n const keysArray = singleOrArray(keys);\n\n const replaceMap: Partial<T> = {};\n\n return items.map((d) => {\n let needsCopy = false;\n for (const key of keysArray) {\n if (d[key as keyof T] != null) {\n replaceMap[key as keyof T] = d[key as keyof T];\n } else if (replaceMap[key as keyof T] != null) {\n needsCopy = true;\n }\n }\n if (!needsCopy) return d;\n const obj = { ...d };\n for (const key of keysArray) {\n if (obj[key as keyof T] == null && replaceMap[key as keyof T] != null) {\n obj[key as keyof T] = replaceMap[key as keyof T] as any;\n }\n }\n return obj;\n });\n };\n\n return _fill;\n}\n"],"names":["singleOrArray"],"mappings":";;;;AAMO,SAAS,KAAuB,IAAqC,EAAA;AAC1E,EAAM,MAAA,KAAA,GAAmB,CAAC,KAAoB,KAAA;AAC5C,IAAM,MAAA,SAAA,GAAYA,4BAAc,IAAI,CAAA,CAAA;AAEpC,IAAA,MAAM,aAAyB,EAAC,CAAA;AAEhC,IAAO,OAAA,KAAA,CAAM,GAAI,CAAA,CAAC,CAAM,KAAA;AACtB,MAAA,IAAI,SAAY,GAAA,KAAA,CAAA;AAChB,MAAA,KAAA,MAAW,OAAO,SAAW,EAAA;AAC3B,QAAI,IAAA,CAAA,CAAE,GAAc,CAAA,IAAK,IAAM,EAAA;AAC7B,UAAW,UAAA,CAAA,GAAc,CAAI,GAAA,CAAA,CAAE,GAAc,CAAA,CAAA;AAAA,SACpC,MAAA,IAAA,UAAA,CAAW,GAAc,CAAA,IAAK,IAAM,EAAA;AAC7C,UAAY,SAAA,GAAA,IAAA,CAAA;AAAA,SACd;AAAA,OACF;AACA,MAAI,IAAA,CAAC,WAAkB,OAAA,CAAA,CAAA;AACvB,MAAM,MAAA,GAAA,GAAM,EAAE,GAAG,CAAE,EAAA,CAAA;AACnB,MAAA,KAAA,MAAW,OAAO,SAAW,EAAA;AAC3B,QAAA,IAAI,IAAI,GAAc,CAAA,IAAK,QAAQ,UAAW,CAAA,GAAc,KAAK,IAAM,EAAA;AACrE,UAAI,GAAA,CAAA,GAAc,CAAI,GAAA,UAAA,CAAW,GAAc,CAAA,CAAA;AAAA,SACjD;AAAA,OACF;AACA,MAAO,OAAA,GAAA,CAAA;AAAA,KACR,CAAA,CAAA;AAAA,GACH,CAAA;AAEA,EAAO,OAAA,KAAA,CAAA;AACT;;;;"}
|
package/dist/lib/filter.js
CHANGED
package/dist/lib/filter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sources":["../../src/filter.ts"],"sourcesContent":["import { TidyFn } from './types';\n\n/**\n * Filters items\n * @param filterFn Returns true to keep the item, false to filter out\n */\nexport function filter<T extends object, O extends T>(\n filterFn: (item: T, index: number, array: T[]) => item is O\n): TidyFn<T, O>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T> {\n const _filter: TidyFn<T> = (items: T[]): T[] => items.filter(filterFn);\n return _filter;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"filter.js","sources":["../../src/filter.ts"],"sourcesContent":["import { TidyFn } from './types';\n\n/**\n * Filters items\n * @param filterFn Returns true to keep the item, false to filter out\n */\nexport function filter<T extends object, O extends T>(\n filterFn: (item: T, index: number, array: T[]) => item is O\n): TidyFn<T, O>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T>;\nexport function filter<T extends object>(\n filterFn: (item: T, index: number, array: T[]) => boolean\n): TidyFn<T> {\n const _filter: TidyFn<T> = (items: T[]): T[] => items.filter(filterFn);\n return _filter;\n}\n"],"names":[],"mappings":";;AAYO,SAAS,OACd,QACW,EAAA;AACX,EAAA,MAAM,OAAqB,GAAA,CAAC,KAAoB,KAAA,KAAA,CAAM,OAAO,QAAQ,CAAA,CAAA;AACrE,EAAO,OAAA,OAAA,CAAA;AACT;;;;"}
|
package/dist/lib/fullJoin.js
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var innerJoin = require('./innerJoin.js');
|
|
6
4
|
|
|
7
5
|
function fullJoin(itemsToJoin, options) {
|
|
8
6
|
const _fullJoin = (items) => {
|
|
9
|
-
if (!itemsToJoin.length)
|
|
10
|
-
|
|
11
|
-
if (!items.length)
|
|
12
|
-
return itemsToJoin;
|
|
7
|
+
if (!itemsToJoin.length) return items;
|
|
8
|
+
if (!items.length) return itemsToJoin;
|
|
13
9
|
const byMap = (options == null ? void 0 : options.by) == null ? innerJoin.autodetectByMap(items, itemsToJoin) : innerJoin.makeByMap(options.by);
|
|
14
|
-
const
|
|
10
|
+
const joinKeys = Object.keys(byMap);
|
|
11
|
+
const itemKeys = joinKeys.map((jKey) => byMap[jKey]);
|
|
12
|
+
const index = innerJoin.buildJoinIndex(itemsToJoin, joinKeys);
|
|
13
|
+
const matchedItems = /* @__PURE__ */ new Set();
|
|
15
14
|
const joinObjectKeys = Object.keys(itemsToJoin[0]);
|
|
16
15
|
const joined = items.flatMap((d) => {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const key = innerJoin.computeKey(d, itemKeys);
|
|
17
|
+
const matches = index.get(key);
|
|
18
|
+
if (matches !== void 0) {
|
|
19
|
+
for (const j of matches) {
|
|
20
|
+
matchedItems.add(j);
|
|
21
21
|
}
|
|
22
|
-
return
|
|
23
|
-
});
|
|
24
|
-
if (matches.length) {
|
|
25
|
-
return matches.map((j) => ({...d, ...j}));
|
|
22
|
+
return matches.map((j) => ({ ...d, ...j }));
|
|
26
23
|
}
|
|
27
|
-
const undefinedFill = Object.fromEntries(
|
|
28
|
-
|
|
24
|
+
const undefinedFill = Object.fromEntries(
|
|
25
|
+
joinObjectKeys.filter((key2) => d[key2] == null).map((key2) => [key2, void 0])
|
|
26
|
+
);
|
|
27
|
+
return { ...d, ...undefinedFill };
|
|
29
28
|
});
|
|
30
|
-
if (
|
|
31
|
-
const leftEmptyObject = Object.fromEntries(
|
|
29
|
+
if (matchedItems.size < itemsToJoin.length) {
|
|
30
|
+
const leftEmptyObject = Object.fromEntries(
|
|
31
|
+
Object.keys(items[0]).map((key) => [key, void 0])
|
|
32
|
+
);
|
|
32
33
|
for (const item of itemsToJoin) {
|
|
33
|
-
if (!
|
|
34
|
-
joined.push({...leftEmptyObject, ...item});
|
|
34
|
+
if (!matchedItems.has(item)) {
|
|
35
|
+
joined.push({ ...leftEmptyObject, ...item });
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
}
|
package/dist/lib/fullJoin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fullJoin.js","sources":["../../src/fullJoin.ts"],"sourcesContent":["import { Datum, TidyFn } from './types';\nimport {
|
|
1
|
+
{"version":3,"file":"fullJoin.js","sources":["../../src/fullJoin.ts"],"sourcesContent":["import { Datum, TidyFn } from './types';\nimport {\n makeByMap,\n autodetectByMap,\n JoinOptions,\n buildJoinIndex,\n computeKey,\n} from './innerJoin';\nimport { Merge } from './type-utils';\n\n/**\n * Performs a full join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function fullJoin<T extends Datum, JoinT extends Datum>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, Merge<T, Partial<JoinT>>> {\n const _fullJoin: TidyFn<T, Merge<T, Partial<JoinT>>> = (\n items: T[]\n ): Merge<T, Partial<JoinT>>[] => {\n if (!itemsToJoin.length) return items as any;\n if (!items.length) return itemsToJoin as any;\n\n // convert by option in to a map from T key to JoinT key\n const byMap =\n options?.by == null\n ? autodetectByMap(items, itemsToJoin)\n : makeByMap(options.by);\n\n const joinKeys = Object.keys(byMap);\n const itemKeys = joinKeys.map((jKey) => byMap[jKey] as string);\n const index = buildJoinIndex(itemsToJoin, joinKeys);\n\n // keep track of matched join items by reference\n const matchedItems = new Set<JoinT>();\n\n // when we miss a join, we want to explicitly add in undefined\n // so our rows all have the same keys. get those keys here.\n const joinObjectKeys = Object.keys(itemsToJoin[0]);\n\n const joined = items.flatMap((d: T) => {\n const key = computeKey(d, itemKeys);\n const matches = index.get(key);\n\n if (matches !== undefined) {\n for (const j of matches) {\n matchedItems.add(j);\n }\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n }\n\n // add in missing keys explicitly as undefined without\n // overriding existing values and while maintaining order\n // of keys\n const undefinedFill = Object.fromEntries(\n joinObjectKeys\n .filter((key) => d[key] == null)\n .map((key) => [key, undefined])\n );\n\n return { ...d, ...undefinedFill };\n });\n\n // add in the ones we missed\n if (matchedItems.size < itemsToJoin.length) {\n const leftEmptyObject = Object.fromEntries(\n Object.keys(items[0]).map((key) => [key, undefined])\n );\n for (const item of itemsToJoin) {\n if (!matchedItems.has(item)) {\n joined.push({ ...leftEmptyObject, ...item });\n }\n }\n }\n\n return joined;\n };\n return _fullJoin;\n}\n"],"names":["autodetectByMap","makeByMap","buildJoinIndex","computeKey","key"],"mappings":";;;;AAcgB,SAAA,QAAA,CACd,aACA,OACqC,EAAA;AACrC,EAAM,MAAA,SAAA,GAAiD,CACrD,KAC+B,KAAA;AAC/B,IAAI,IAAA,CAAC,WAAY,CAAA,MAAA,EAAe,OAAA,KAAA,CAAA;AAChC,IAAI,IAAA,CAAC,KAAM,CAAA,MAAA,EAAe,OAAA,WAAA,CAAA;AAG1B,IAAM,MAAA,KAAA,GAAA,CACJ,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,EAAA,KAAM,IACX,GAAAA,yBAAA,CAAgB,OAAO,WAAW,CAAA,GAClCC,mBAAU,CAAA,OAAA,CAAQ,EAAE,CAAA,CAAA;AAE1B,IAAM,MAAA,QAAA,GAAW,MAAO,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAClC,IAAA,MAAM,WAAW,QAAS,CAAA,GAAA,CAAI,CAAC,IAAS,KAAA,KAAA,CAAM,IAAI,CAAW,CAAA,CAAA;AAC7D,IAAM,MAAA,KAAA,GAAQC,wBAAe,CAAA,WAAA,EAAa,QAAQ,CAAA,CAAA;AAGlD,IAAM,MAAA,YAAA,uBAAmB,GAAW,EAAA,CAAA;AAIpC,IAAA,MAAM,cAAiB,GAAA,MAAA,CAAO,IAAK,CAAA,WAAA,CAAY,CAAC,CAAC,CAAA,CAAA;AAEjD,IAAA,MAAM,MAAS,GAAA,KAAA,CAAM,OAAQ,CAAA,CAAC,CAAS,KAAA;AACrC,MAAM,MAAA,GAAA,GAAMC,oBAAW,CAAA,CAAA,EAAG,QAAQ,CAAA,CAAA;AAClC,MAAM,MAAA,OAAA,GAAU,KAAM,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAE7B,MAAA,IAAI,YAAY,KAAW,CAAA,EAAA;AACzB,QAAA,KAAA,MAAW,KAAK,OAAS,EAAA;AACvB,UAAA,YAAA,CAAa,IAAI,CAAC,CAAA,CAAA;AAAA,SACpB;AACA,QAAO,OAAA,OAAA,CAAQ,IAAI,CAAC,CAAA,MAAc,EAAE,GAAG,CAAA,EAAG,GAAG,CAAA,EAAI,CAAA,CAAA,CAAA;AAAA,OACnD;AAKA,MAAA,MAAM,gBAAgB,MAAO,CAAA,WAAA;AAAA,QAC3B,cACG,CAAA,MAAA,CAAO,CAACC,IAAAA,KAAQ,EAAEA,IAAG,CAAA,IAAK,IAAI,CAAA,CAC9B,IAAI,CAACA,IAAAA,KAAQ,CAACA,IAAAA,EAAK,MAAS,CAAC,CAAA;AAAA,OAClC,CAAA;AAEA,MAAA,OAAO,EAAE,GAAG,CAAG,EAAA,GAAG,aAAc,EAAA,CAAA;AAAA,KACjC,CAAA,CAAA;AAGD,IAAI,IAAA,YAAA,CAAa,IAAO,GAAA,WAAA,CAAY,MAAQ,EAAA;AAC1C,MAAA,MAAM,kBAAkB,MAAO,CAAA,WAAA;AAAA,QAC7B,MAAO,CAAA,IAAA,CAAK,KAAM,CAAA,CAAC,CAAC,CAAA,CAAE,GAAI,CAAA,CAAC,GAAQ,KAAA,CAAC,GAAK,EAAA,KAAA,CAAS,CAAC,CAAA;AAAA,OACrD,CAAA;AACA,MAAA,KAAA,MAAW,QAAQ,WAAa,EAAA;AAC9B,QAAA,IAAI,CAAC,YAAA,CAAa,GAAI,CAAA,IAAI,CAAG,EAAA;AAC3B,UAAA,MAAA,CAAO,KAAK,EAAE,GAAG,eAAiB,EAAA,GAAG,MAAM,CAAA,CAAA;AAAA,SAC7C;AAAA,OACF;AAAA,KACF;AAEA,IAAO,OAAA,MAAA,CAAA;AAAA,GACT,CAAA;AACA,EAAO,OAAA,SAAA,CAAA;AACT;;;;"}
|
package/dist/lib/groupBy.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var d3Array = require('d3-array');
|
|
6
4
|
var assignGroupKeys = require('./helpers/assignGroupKeys.js');
|
|
7
5
|
var groupMap = require('./helpers/groupMap.js');
|
|
@@ -16,9 +14,13 @@ function groupBy(groupKeys, fns, options) {
|
|
|
16
14
|
} else if (arguments.length === 2 && fns != null && !Array.isArray(fns)) {
|
|
17
15
|
options = fns;
|
|
18
16
|
}
|
|
19
|
-
const _groupBy = (items) => {
|
|
17
|
+
const _groupBy = ((items) => {
|
|
20
18
|
const grouped = makeGrouped(items, groupKeys);
|
|
21
|
-
const results = runFlow(
|
|
19
|
+
const results = runFlow(
|
|
20
|
+
grouped,
|
|
21
|
+
fns,
|
|
22
|
+
options == null ? void 0 : options.addGroupKeys
|
|
23
|
+
);
|
|
22
24
|
if (options == null ? void 0 : options.export) {
|
|
23
25
|
switch (options.export) {
|
|
24
26
|
case "grouped":
|
|
@@ -42,29 +44,33 @@ function groupBy(groupKeys, fns, options) {
|
|
|
42
44
|
}
|
|
43
45
|
const ungrouped = ungroup(results, options == null ? void 0 : options.addGroupKeys);
|
|
44
46
|
return ungrouped;
|
|
45
|
-
};
|
|
47
|
+
});
|
|
46
48
|
return _groupBy;
|
|
47
49
|
}
|
|
48
|
-
groupBy.grouped = (options) => ({...options, export: "grouped"});
|
|
49
|
-
groupBy.entries = (options) => ({...options, export: "entries"});
|
|
50
|
-
groupBy.entriesObject = (options) => ({...options, export: "entries-object"});
|
|
51
|
-
groupBy.object = (options) => ({...options, export: "object"});
|
|
52
|
-
groupBy.map = (options) => ({...options, export: "map"});
|
|
53
|
-
groupBy.keys = (options) => ({...options, export: "keys"});
|
|
54
|
-
groupBy.values = (options) => ({...options, export: "values"});
|
|
55
|
-
groupBy.levels = (options) => ({...options, export: "levels"});
|
|
50
|
+
groupBy.grouped = (options) => ({ ...options, export: "grouped" });
|
|
51
|
+
groupBy.entries = (options) => ({ ...options, export: "entries" });
|
|
52
|
+
groupBy.entriesObject = (options) => ({ ...options, export: "entries-object" });
|
|
53
|
+
groupBy.object = (options) => ({ ...options, export: "object" });
|
|
54
|
+
groupBy.map = (options) => ({ ...options, export: "map" });
|
|
55
|
+
groupBy.keys = (options) => ({ ...options, export: "keys" });
|
|
56
|
+
groupBy.values = (options) => ({ ...options, export: "values" });
|
|
57
|
+
groupBy.levels = (options) => ({ ...options, export: "levels" });
|
|
56
58
|
function runFlow(items, fns, addGroupKeys) {
|
|
57
59
|
let result = items;
|
|
58
|
-
if (!(fns == null ? void 0 : fns.length))
|
|
59
|
-
return result;
|
|
60
|
+
if (!(fns == null ? void 0 : fns.length)) return result;
|
|
60
61
|
for (const fn of fns) {
|
|
61
|
-
if (!fn)
|
|
62
|
-
continue;
|
|
62
|
+
if (!fn) continue;
|
|
63
63
|
result = groupMap.groupMap(result, (items2, keys) => {
|
|
64
|
-
const
|
|
64
|
+
const keysSnapshot = keys.slice();
|
|
65
|
+
const context = { groupKeys: keysSnapshot };
|
|
65
66
|
let leafItemsMapped = fn(items2, context);
|
|
66
67
|
if (addGroupKeys !== false) {
|
|
67
|
-
|
|
68
|
+
const filteredKeys = keysSnapshot.filter(
|
|
69
|
+
(key) => typeof key[0] !== "function" && key[0] != null
|
|
70
|
+
);
|
|
71
|
+
leafItemsMapped = leafItemsMapped.map(
|
|
72
|
+
(item) => assignGroupKeys.assignGroupKeys(item, keysSnapshot, filteredKeys)
|
|
73
|
+
);
|
|
68
74
|
}
|
|
69
75
|
return leafItemsMapped;
|
|
70
76
|
});
|
|
@@ -72,9 +78,9 @@ function runFlow(items, fns, addGroupKeys) {
|
|
|
72
78
|
return result;
|
|
73
79
|
}
|
|
74
80
|
function makeGrouped(items, groupKeys) {
|
|
75
|
-
const groupKeyFns = singleOrArray.singleOrArray(groupKeys).map((key
|
|
81
|
+
const groupKeyFns = singleOrArray.singleOrArray(groupKeys).map((key) => {
|
|
76
82
|
const keyFn = typeof key === "function" ? key : (d) => d[key];
|
|
77
|
-
const keyCache = new Map();
|
|
83
|
+
const keyCache = /* @__PURE__ */ new Map();
|
|
78
84
|
return (d) => {
|
|
79
85
|
const keyValue = keyFn(d);
|
|
80
86
|
const keyValueOf = isObject.isObject(keyValue) ? keyValue.valueOf() : keyValue;
|
|
@@ -94,7 +100,10 @@ function ungroup(grouped, addGroupKeys) {
|
|
|
94
100
|
groupTraversal.groupTraversal(grouped, items, [], identity.identity, (root, keys, values) => {
|
|
95
101
|
let valuesToAdd = values;
|
|
96
102
|
if (addGroupKeys !== false) {
|
|
97
|
-
|
|
103
|
+
const filteredKeys = keys.filter(
|
|
104
|
+
(key) => typeof key[0] !== "function" && key[0] != null
|
|
105
|
+
);
|
|
106
|
+
valuesToAdd = values.map((d) => assignGroupKeys.assignGroupKeys(d, keys, filteredKeys));
|
|
98
107
|
}
|
|
99
108
|
root.push(...valuesToAdd);
|
|
100
109
|
});
|
|
@@ -115,23 +124,30 @@ function processFromGroupsOptions(options) {
|
|
|
115
124
|
compositeKey = (_a = options.compositeKey) != null ? _a : defaultCompositeKey;
|
|
116
125
|
}
|
|
117
126
|
const groupFn = (values, keys) => {
|
|
118
|
-
return single ? mapLeaf(
|
|
127
|
+
return single ? mapLeaf(
|
|
128
|
+
addGroupKeys === false ? values[0] : assignGroupKeys.assignGroupKeys(values[0], keys)
|
|
129
|
+
) : mapLeaves(
|
|
130
|
+
values.map(
|
|
131
|
+
(d) => mapLeaf(addGroupKeys === false ? d : assignGroupKeys.assignGroupKeys(d, keys))
|
|
132
|
+
)
|
|
133
|
+
);
|
|
119
134
|
};
|
|
120
135
|
const keyFn = flat ? (keys) => compositeKey(keys.map((d) => d[1])) : (keys) => keys[keys.length - 1][1];
|
|
121
|
-
return {groupFn, keyFn};
|
|
136
|
+
return { groupFn, keyFn };
|
|
122
137
|
}
|
|
123
138
|
function exportLevels(grouped, options) {
|
|
124
|
-
const {groupFn, keyFn} = processFromGroupsOptions(options);
|
|
125
|
-
let {mapEntry = identity.identity} = options;
|
|
126
|
-
const {levels = ["entries"]} = options;
|
|
139
|
+
const { groupFn, keyFn } = processFromGroupsOptions(options);
|
|
140
|
+
let { mapEntry = identity.identity } = options;
|
|
141
|
+
const { levels = ["entries"] } = options;
|
|
127
142
|
const levelSpecs = [];
|
|
128
143
|
for (const levelOption of levels) {
|
|
129
144
|
switch (levelOption) {
|
|
145
|
+
// entries / entries-object -----------------------------------------
|
|
130
146
|
case "entries":
|
|
131
147
|
case "entries-object":
|
|
132
148
|
case "entries-obj":
|
|
133
149
|
case "entriesObject": {
|
|
134
|
-
const levelMapEntry = (levelOption === "entries-object" || levelOption === "entries-obj" || levelOption === "entriesObject") && options.mapEntry == null ? ([key, values]) => ({key, values}) : mapEntry;
|
|
150
|
+
const levelMapEntry = (levelOption === "entries-object" || levelOption === "entries-obj" || levelOption === "entriesObject") && options.mapEntry == null ? ([key, values]) => ({ key, values }) : mapEntry;
|
|
135
151
|
levelSpecs.push({
|
|
136
152
|
id: "entries",
|
|
137
153
|
createEmptySubgroup: () => [],
|
|
@@ -144,10 +160,11 @@ function exportLevels(grouped, options) {
|
|
|
144
160
|
});
|
|
145
161
|
break;
|
|
146
162
|
}
|
|
163
|
+
// map -------------------------------------------------------------
|
|
147
164
|
case "map":
|
|
148
165
|
levelSpecs.push({
|
|
149
166
|
id: "map",
|
|
150
|
-
createEmptySubgroup: () => new Map(),
|
|
167
|
+
createEmptySubgroup: () => /* @__PURE__ */ new Map(),
|
|
151
168
|
addSubgroup: (parentGrouped, newSubgroup, key) => {
|
|
152
169
|
parentGrouped.set(key, newSubgroup);
|
|
153
170
|
},
|
|
@@ -156,6 +173,7 @@ function exportLevels(grouped, options) {
|
|
|
156
173
|
}
|
|
157
174
|
});
|
|
158
175
|
break;
|
|
176
|
+
// object ----------------------------------------------------------
|
|
159
177
|
case "object":
|
|
160
178
|
levelSpecs.push({
|
|
161
179
|
id: "object",
|
|
@@ -168,6 +186,7 @@ function exportLevels(grouped, options) {
|
|
|
168
186
|
}
|
|
169
187
|
});
|
|
170
188
|
break;
|
|
189
|
+
// keys ------------------------------------------------------------
|
|
171
190
|
case "keys":
|
|
172
191
|
levelSpecs.push({
|
|
173
192
|
id: "keys",
|
|
@@ -180,6 +199,7 @@ function exportLevels(grouped, options) {
|
|
|
180
199
|
}
|
|
181
200
|
});
|
|
182
201
|
break;
|
|
202
|
+
// values ----------------------------------------------------------
|
|
183
203
|
case "values":
|
|
184
204
|
levelSpecs.push({
|
|
185
205
|
id: "values",
|
|
@@ -192,6 +212,7 @@ function exportLevels(grouped, options) {
|
|
|
192
212
|
}
|
|
193
213
|
});
|
|
194
214
|
break;
|
|
215
|
+
// custom ----------------------------------------------------------
|
|
195
216
|
default: {
|
|
196
217
|
if (typeof levelOption === "object") {
|
|
197
218
|
levelSpecs.push(levelOption);
|
|
@@ -213,7 +234,12 @@ function exportLevels(grouped, options) {
|
|
|
213
234
|
const addLeaf = (parentGrouped, keys, values, level) => {
|
|
214
235
|
var _a;
|
|
215
236
|
const levelSpec = (_a = levelSpecs[level]) != null ? _a : levelSpecs[levelSpecs.length - 1];
|
|
216
|
-
levelSpec.addLeaf(
|
|
237
|
+
levelSpec.addLeaf(
|
|
238
|
+
parentGrouped,
|
|
239
|
+
keyFn(keys),
|
|
240
|
+
groupFn(values, keys),
|
|
241
|
+
level
|
|
242
|
+
);
|
|
217
243
|
};
|
|
218
244
|
const initialOutputObject = levelSpecs[0].createEmptySubgroup();
|
|
219
245
|
return groupTraversal.groupTraversal(grouped, initialOutputObject, [], addSubgroup, addLeaf);
|
package/dist/lib/groupBy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupBy.js","sources":["../../src/groupBy.ts"],"sourcesContent":["import { group } from 'd3-array';\nimport { A, O } from 'ts-toolbelt';\nimport { assignGroupKeys } from './helpers/assignGroupKeys';\nimport { groupMap } from './helpers/groupMap';\nimport { groupTraversal } from './helpers/groupTraversal';\nimport { identity } from './helpers/identity';\nimport { isObject } from './helpers/isObject';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Grouped, GroupKey, TidyGroupExportFn, Key, TidyFn } from './types';\n\n/** [key, values] where values could be more nested entries */\ntype EntriesOutput = [any, any][];\ntype EntriesObjectOutput = { key: Key; values: any }[];\n\n/** nested objects: { [key]: values } */\ntype ObjectOutput = Record<Key, any>;\n\n/** nested keys: e.g. [key, key, key, [key, key, [key]]] */\ntype KeysOutput = any[];\n\n/** nested values: e.g. [[value1_1, value1_2], [value2_1, value2_2]] */\ntype ValuesOutput = any[];\n\nexport type LevelSpec = {\n id?: string;\n createEmptySubgroup: () => any;\n addSubgroup: (\n parentGrouped: any,\n newSubgroup: any,\n key: any,\n level: number\n ) => void;\n addLeaf: (parentGrouped: any, key: any, values: any[], level: number) => void;\n};\n\n/**\n * Options to affect export type\n */\ninterface GroupByOptions {\n /** whether to merge group keys back into the objects */\n readonly addGroupKeys?: boolean;\n\n // -- export related -- //\n /** export method */\n readonly export?:\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n | 'ungrouped';\n /** if all nested levels should be brought to a single top level */\n readonly flat?: boolean;\n /** when flat is true, how to flatten nested keys */\n readonly compositeKey?: (keys: any[]) => string;\n /** whether the leaf sets consist of just one item (typical after summarize).\n * if true, uses the first element in the leaf set instead of an array\n */\n readonly single?: boolean;\n /** operation called on each leaf during export to map it to a different value\n * (default: identity)\n */\n readonly mapLeaf?: (value: any) => any;\n /** operation called on each leaf set to map the array of values to a different value.\n * Similar to `rollup` from d3-collection nest or d3-array\n * (default: identity)\n */\n readonly mapLeaves?: (values: any[]) => any;\n /** [entries only] operation called on entries to map from [key, values] to\n * whatever the output of this is (e.g. `{ key, values }`)\n * (default: identity)\n */\n readonly mapEntry?: (entry: [any, any], level: number) => any;\n\n /** [required for levels] specifies the export operation for each level of the grouping */\n readonly levels?: (\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | LevelSpec\n )[];\n}\n\n// aliases to make overloads shorter\ntype GK<T extends object> = SingleOrArray<keyof T | ((d: T) => any)>;\ntype F<I extends object, O extends object> = TidyFn<I, O>;\n\n// merge back in group keys to output types\ntype MergeGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>\n> = Keys extends keyof T\n ? O.Merge<Pick<T, Keys>, Out>\n : Keys extends (keyof T)[]\n ? O.Merge<Pick<T, Keys[number]>, Out>\n : Out;\n\n// do not merge in group keys if explicitly said not to\ntype WithGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = NonNullable<Opts>['addGroupKeys'] extends false\n ? Out\n : MergeGroupKeys<T, Out, Keys>;\n\n/**\n * output varies based on export options\n */\ntype GroupByOutput<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = A.Compute<\n NonNullable<Opts>['export'] extends 'grouped'\n ? Grouped<WithGroupKeys<T, O, Keys, Opts>>\n : NonNullable<Opts>['export'] extends 'entries'\n ? EntriesOutput\n : NonNullable<Opts>['export'] extends 'entries-object'\n ? EntriesObjectOutput\n : NonNullable<Opts>['export'] extends 'object'\n ? ObjectOutput\n : NonNullable<Opts>['export'] extends 'map'\n ? Map<any, any>\n : NonNullable<Opts>['export'] extends 'keys'\n ? KeysOutput\n : NonNullable<Opts>['export'] extends 'values'\n ? ValuesOutput\n : NonNullable<Opts>['export'] extends 'levels'\n ? any\n : WithGroupKeys<T, O, Keys, Opts>[]\n>;\n\ntype GroupByFn<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = Opts['export'] extends\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n ? TidyGroupExportFn<T, GroupByOutput<T, O, Keys, Opts>>\n : // default is no export, ungrouped and back in simple form\n TidyFn<T, WithGroupKeys<T, O, Keys, Opts>>;\n\n/**\n * Nests the data by the specified groupings\n */\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: F<T, T1>, options: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: F<T, T1>): GroupByFn<T, T1, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>, F<T6, T7>], options: Opts): GroupByFn<T, T7, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>, F<T6, T7>]): GroupByFn<T, T7, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>], options: Opts): GroupByFn<T, T6, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>]): GroupByFn<T, T6, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>], options: Opts): GroupByFn<T, T5, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>]): GroupByFn<T, T5, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>], options: Opts): GroupByFn<T, T4, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>]): GroupByFn<T, T4, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>], options: Opts): GroupByFn<T, T3, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>]): GroupByFn<T, T3, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>], options: Opts): GroupByFn<T, T2, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>]): GroupByFn<T, T2, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>], options: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>]): GroupByFn<T, T1, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [], options: Opts): GroupByFn<T, T, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>>(groupKeys: Keys, fns: []): GroupByFn<T, T, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, options: Opts): GroupByFn<T, T, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, Keys extends GK<T>>(groupKeys: Keys): GroupByFn<T, T, Keys, GroupByOptions>;\nexport function groupBy<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n>(\n groupKeys: Keys,\n fns?: TidyFn<any, any>[] | TidyFn<any, any>,\n options?: Opts\n): GroupByFn<T, O, Keys, Opts> {\n if (typeof fns === 'function') {\n fns = [fns];\n } else if (arguments.length === 2 && fns != null && !Array.isArray(fns)) {\n options = fns as any;\n }\n\n const _groupBy: GroupByFn<T, O, Keys, Opts> = ((items: T[]) => {\n // form into a nested map\n const grouped = makeGrouped(items, groupKeys);\n\n // run group functions\n const results = runFlow(\n grouped,\n fns as TidyFn<any, any>[],\n options?.addGroupKeys\n );\n\n // export\n if (options?.export) {\n switch (options.export) {\n case 'grouped':\n return results;\n case 'levels':\n return exportLevels(results, options);\n case 'entries-obj' as any:\n case 'entriesObject' as any:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: ['entries-object'],\n });\n default:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: [options.export],\n });\n }\n }\n\n // export === 'ungrouped' or nully:\n const ungrouped = ungroup(results, options?.addGroupKeys);\n return ungrouped as any;\n }) as GroupByFn<T, O, Keys, Opts>;\n // (_groupBy as any).tidyType = 'group-export';\n\n return _groupBy;\n}\n// convenient export option configs\ngroupBy.grouped = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'grouped' } as const);\ngroupBy.entries = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries' } as const);\ngroupBy.entriesObject = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries-object' } as const);\ngroupBy.object = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'object' } as const);\ngroupBy.map = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'map' } as const);\ngroupBy.keys = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'keys' } as const);\ngroupBy.values = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'values' } as const);\ngroupBy.levels = (options?: Omit<GroupByOptions, 'export'>) =>\n ({ ...options, export: 'levels' } as const);\n\nfunction runFlow<T extends object>(\n items: Grouped<T>,\n fns?: TidyFn<any, any>[],\n addGroupKeys?: boolean\n) {\n let result: any = items;\n if (!fns?.length) return result;\n\n for (const fn of fns) {\n if (!fn) continue;\n\n // otherwise break it up and call it on each leaf set\n result = groupMap(result, (items, keys) => {\n // ensure we kept the group keys in the object\n // (necessary for e.g. summarize which may remove them)\n const context = { groupKeys: keys };\n let leafItemsMapped = fn(items, context);\n if (addGroupKeys !== false) {\n leafItemsMapped = leafItemsMapped.map((item: T) =>\n assignGroupKeys(item, keys)\n );\n }\n\n return leafItemsMapped;\n });\n }\n\n return result;\n}\n\nfunction makeGrouped<T extends object>(\n items: T[],\n groupKeys: SingleOrArray<keyof T | ((d: T) => any)>\n): Grouped<T> {\n // convert string based keys to functions and keep the key name with the key value in a tuple\n const groupKeyFns = singleOrArray(groupKeys).map((key, i) => {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n // use a cache so we don't generate new keys for the same tuple\n const keyCache = new Map();\n return (d: T) => {\n const keyValue = keyFn(d);\n\n const keyValueOf = isObject(keyValue) ? keyValue.valueOf() : keyValue;\n // used cache tuple if available\n if (keyCache.has(keyValueOf)) {\n return keyCache.get(keyValueOf) as GroupKey;\n }\n\n const keyWithName = [key, keyValue];\n keyCache.set(keyValueOf, keyWithName);\n\n return keyWithName;\n };\n });\n\n const grouped = group(items, ...groupKeyFns);\n return grouped;\n}\n\n/**\n * flattens a grouped collection back to a simple array\n */\nfunction ungroup<T extends object>(\n grouped: Grouped<T>,\n addGroupKeys: boolean | undefined\n): T[] {\n // flatten the groups\n const items: T[] = [];\n\n groupTraversal(grouped, items, [], identity, (root, keys, values) => {\n // ensure we have group keys on items (in case runFlow didn't run)\n let valuesToAdd = values;\n if (addGroupKeys !== false) {\n valuesToAdd = values.map((d) => assignGroupKeys(d, keys));\n }\n root.push(...valuesToAdd);\n });\n\n return items;\n}\n\n// -----------------------------------------------------------------------\n// --- EXPORTS -----------------------------------------------------------\n// -----------------------------------------------------------------------\nconst defaultCompositeKey = (keys: any[]) => keys.join('/');\n\nfunction processFromGroupsOptions<T extends object>(options: GroupByOptions) {\n const {\n flat,\n single,\n mapLeaf = identity,\n mapLeaves = identity,\n addGroupKeys,\n } = options;\n let compositeKey: (keys: any[]) => string;\n if (options.flat) {\n compositeKey = options.compositeKey! ?? defaultCompositeKey;\n }\n\n const groupFn = (values: T[], keys: any[]) => {\n return single\n ? mapLeaf(\n addGroupKeys === false ? values[0] : assignGroupKeys(values[0], keys)\n )\n : mapLeaves(\n values.map((d) =>\n mapLeaf(addGroupKeys === false ? d : assignGroupKeys(d, keys))\n )\n );\n };\n\n const keyFn = flat\n ? (keys: GroupKey[]) => compositeKey(keys.map((d) => d[1]))\n : (keys: GroupKey[]) => keys[keys.length - 1][1];\n\n return { groupFn, keyFn };\n}\n\n// -- Levels -------------------------------------------------------------\nfunction exportLevels<T extends object>(\n grouped: Grouped<T>,\n options: GroupByOptions\n): any {\n type NestedEntries<T> = Array<[any, NestedEntries<T> | T[]]>;\n type NestedObject<T> = { [key: string]: NestedObject<T> | T[] };\n\n const { groupFn, keyFn } = processFromGroupsOptions(options);\n let { mapEntry = identity } = options;\n const { levels = ['entries'] } = options;\n\n const levelSpecs: LevelSpec[] = [];\n for (const levelOption of levels) {\n switch (levelOption) {\n // entries / entries-object -----------------------------------------\n case 'entries':\n case 'entries-object':\n case 'entries-obj' as any:\n case 'entriesObject' as any: {\n const levelMapEntry =\n (levelOption === 'entries-object' ||\n levelOption === ('entries-obj' as any) ||\n levelOption === ('entriesObject' as any)) &&\n options.mapEntry == null\n ? ([key, values]: any) => ({ key, values })\n : mapEntry;\n\n levelSpecs.push({\n id: 'entries',\n createEmptySubgroup: () => [],\n addSubgroup: (\n parentGrouped: NestedEntries<T>,\n newSubgroup: any,\n key: any,\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, newSubgroup], level));\n },\n\n addLeaf: (\n parentGrouped: NestedEntries<T>,\n key: any,\n values: T[],\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, values], level));\n },\n });\n break;\n }\n // map -------------------------------------------------------------\n case 'map':\n levelSpecs.push({\n id: 'map',\n createEmptySubgroup: () => new Map(),\n addSubgroup: (\n parentGrouped: Map<any, any>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped.set(key, newSubgroup);\n },\n\n addLeaf: (parentGrouped: Map<any, any>, key: any, values: T[]) => {\n parentGrouped.set(key, values);\n },\n });\n break;\n\n // object ----------------------------------------------------------\n case 'object':\n levelSpecs.push({\n id: 'object',\n createEmptySubgroup: () => ({}),\n addSubgroup: (\n parentGrouped: NestedObject<T>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped[key] = newSubgroup;\n },\n\n addLeaf: (parentGrouped: NestedObject<T>, key: any, values: T[]) => {\n parentGrouped[key] = values;\n },\n });\n break;\n\n // keys ------------------------------------------------------------\n case 'keys':\n levelSpecs.push({\n id: 'keys',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any, key: any) => {\n parentGrouped.push([key, newSubgroup]);\n },\n\n addLeaf: (parentGrouped: any, key: any) => {\n parentGrouped.push(key);\n },\n });\n break;\n\n // values ----------------------------------------------------------\n case 'values':\n levelSpecs.push({\n id: 'values',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any) => {\n parentGrouped.push(newSubgroup);\n },\n\n addLeaf: (parentGrouped: any, key: any, values: T[]) => {\n parentGrouped.push(values);\n },\n });\n break;\n\n // custom ----------------------------------------------------------\n default: {\n // LevelSpec obj already\n if (typeof levelOption === 'object') {\n levelSpecs.push(levelOption);\n }\n }\n }\n }\n\n // add subgroup\n const addSubgroup = (parentGrouped: any, keys: any[], level: number): any => {\n if (options.flat) {\n return parentGrouped;\n }\n\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n const nextLevelSpec = levelSpecs[level + 1] ?? levelSpec;\n const newSubgroup = nextLevelSpec.createEmptySubgroup();\n levelSpec!.addSubgroup(parentGrouped, newSubgroup, keyFn(keys), level);\n return newSubgroup;\n };\n\n // add leaves\n const addLeaf = (\n parentGrouped: any,\n keys: any[],\n values: T[],\n level: number\n ) => {\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n levelSpec!.addLeaf(\n parentGrouped,\n keyFn(keys),\n groupFn(values, keys),\n level\n );\n };\n\n const initialOutputObject = levelSpecs[0]!.createEmptySubgroup();\n return groupTraversal(grouped, initialOutputObject, [], addSubgroup, addLeaf);\n}\n"],"names":["groupMap","assignGroupKeys","singleOrArray","isObject","group","identity","groupTraversal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"groupBy.js","sources":["../../src/groupBy.ts"],"sourcesContent":["import { group } from 'd3-array';\nimport { Prettify, Merge } from './type-utils';\nimport { assignGroupKeys } from './helpers/assignGroupKeys';\nimport { groupMap } from './helpers/groupMap';\nimport { groupTraversal } from './helpers/groupTraversal';\nimport { identity } from './helpers/identity';\nimport { isObject } from './helpers/isObject';\nimport { SingleOrArray, singleOrArray } from './helpers/singleOrArray';\nimport { Grouped, GroupKey, TidyGroupExportFn, Key, TidyFn } from './types';\n\n/** [key, values] where values could be more nested entries */\ntype EntriesOutput = [any, any][];\ntype EntriesObjectOutput = { key: Key; values: any }[];\n\n/** nested objects: { [key]: values } */\ntype ObjectOutput = Record<Key, any>;\n\n/** nested keys: e.g. [key, key, key, [key, key, [key]]] */\ntype KeysOutput = any[];\n\n/** nested values: e.g. [[value1_1, value1_2], [value2_1, value2_2]] */\ntype ValuesOutput = any[];\n\nexport type LevelSpec = {\n id?: string;\n createEmptySubgroup: () => any;\n addSubgroup: (\n parentGrouped: any,\n newSubgroup: any,\n key: any,\n level: number\n ) => void;\n addLeaf: (parentGrouped: any, key: any, values: any[], level: number) => void;\n};\n\n/**\n * Options to affect export type\n */\ninterface GroupByOptions {\n /** whether to merge group keys back into the objects */\n readonly addGroupKeys?: boolean;\n\n // -- export related -- //\n /** export method */\n readonly export?:\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n | 'ungrouped';\n /** if all nested levels should be brought to a single top level */\n readonly flat?: boolean;\n /** when flat is true, how to flatten nested keys */\n readonly compositeKey?: (keys: any[]) => string;\n /** whether the leaf sets consist of just one item (typical after summarize).\n * if true, uses the first element in the leaf set instead of an array\n */\n readonly single?: boolean;\n /** operation called on each leaf during export to map it to a different value\n * (default: identity)\n */\n readonly mapLeaf?: (value: any) => any;\n /** operation called on each leaf set to map the array of values to a different value.\n * Similar to `rollup` from d3-collection nest or d3-array\n * (default: identity)\n */\n readonly mapLeaves?: (values: any[]) => any;\n /** [entries only] operation called on entries to map from [key, values] to\n * whatever the output of this is (e.g. `{ key, values }`)\n * (default: identity)\n */\n readonly mapEntry?: (entry: [any, any], level: number) => any;\n\n /** [required for levels] specifies the export operation for each level of the grouping */\n readonly levels?: (\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | LevelSpec\n )[];\n}\n\n// aliases to make overloads shorter\ntype GK<T extends object> = SingleOrArray<keyof T | ((d: T) => any)>;\ntype F<I extends object, O extends object> = TidyFn<I, O>;\n\n// merge back in group keys to output types\ntype MergeGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>\n> = Keys extends keyof T\n ? Merge<Pick<T, Keys>, Out>\n : Keys extends (keyof T)[]\n ? Merge<Pick<T, Keys[number]>, Out>\n : Out;\n\n// do not merge in group keys if explicitly said not to\ntype WithGroupKeys<\n T extends object,\n Out extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = NonNullable<Opts>['addGroupKeys'] extends false\n ? Out\n : MergeGroupKeys<T, Out, Keys>;\n\n/**\n * output varies based on export options\n */\ntype GroupByOutput<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = Prettify<\n NonNullable<Opts>['export'] extends 'grouped'\n ? Grouped<WithGroupKeys<T, O, Keys, Opts>>\n : NonNullable<Opts>['export'] extends 'entries'\n ? EntriesOutput\n : NonNullable<Opts>['export'] extends 'entries-object'\n ? EntriesObjectOutput\n : NonNullable<Opts>['export'] extends 'object'\n ? ObjectOutput\n : NonNullable<Opts>['export'] extends 'map'\n ? Map<any, any>\n : NonNullable<Opts>['export'] extends 'keys'\n ? KeysOutput\n : NonNullable<Opts>['export'] extends 'values'\n ? ValuesOutput\n : NonNullable<Opts>['export'] extends 'levels'\n ? any\n : WithGroupKeys<T, O, Keys, Opts>[]\n>;\n\ntype GroupByFn<\n T extends object,\n O extends object,\n Keys extends GK<T>,\n Opts extends GroupByOptions\n> = Opts['export'] extends\n | 'grouped'\n | 'entries'\n | 'entries-object'\n | 'object'\n | 'map'\n | 'keys'\n | 'values'\n | 'levels'\n ? TidyGroupExportFn<T, GroupByOutput<T, O, Keys, Opts>>\n : TidyFn<T, Prettify<WithGroupKeys<T, O, Keys, Opts>>>;\n\n/**\n * Nests the data by the specified groupings\n */\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: F<T, T1>, options: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: F<T, T1>): GroupByFn<T, T1, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>, F<T6, T7>], options: Opts): GroupByFn<T, T7, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, T7 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>, F<T6, T7>]): GroupByFn<T, T7, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>], options: Opts): GroupByFn<T, T6, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, T6 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>, F<T5, T6>]): GroupByFn<T, T6, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>], options: Opts): GroupByFn<T, T5, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, T5 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>, F<T4, T5>]): GroupByFn<T, T5, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>], options: Opts): GroupByFn<T, T4, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, T4 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>, F<T3, T4>]): GroupByFn<T, T4, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>], options: Opts): GroupByFn<T, T3, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, T3 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>, F<T2, T3>]): GroupByFn<T, T3, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>], options: Opts): GroupByFn<T, T2, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, T2 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>, F<T1, T2>]): GroupByFn<T, T2, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [F<T, T1>], options: Opts): GroupByFn<T, T1, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, T1 extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: [F<T, T1>]): GroupByFn<T, T1, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, fns: [], options: Opts): GroupByFn<T, T, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, const Keys extends GK<T>>(groupKeys: Keys, fns: []): GroupByFn<T, T, Keys, GroupByOptions>;\n// prettier-ignore\nexport function groupBy<T extends object, const Keys extends GK<T>, Opts extends GroupByOptions>(groupKeys: Keys, options: Opts): GroupByFn<T, T, Keys, Opts>;\n// prettier-ignore\nexport function groupBy<T extends object, const Keys extends GK<T>>(groupKeys: Keys): GroupByFn<T, T, Keys, GroupByOptions>;\nexport function groupBy<\n T extends object,\n O extends object,\n const Keys extends GK<T>,\n Opts extends GroupByOptions\n>(\n groupKeys: Keys,\n fns?: TidyFn<any, any>[] | TidyFn<any, any>,\n options?: Opts\n): GroupByFn<T, O, Keys, Opts> {\n if (typeof fns === 'function') {\n fns = [fns];\n } else if (arguments.length === 2 && fns != null && !Array.isArray(fns)) {\n options = fns as any;\n }\n\n const _groupBy: GroupByFn<T, O, Keys, Opts> = ((items: T[]) => {\n // form into a nested map\n const grouped = makeGrouped(items, groupKeys);\n\n // run group functions\n const results = runFlow(\n grouped,\n fns as TidyFn<any, any>[],\n options?.addGroupKeys\n );\n\n // export\n if (options?.export) {\n switch (options.export) {\n case 'grouped':\n return results;\n case 'levels':\n return exportLevels(results, options);\n case 'entries-obj' as any:\n case 'entriesObject' as any:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: ['entries-object'],\n });\n default:\n return exportLevels(results, {\n ...options,\n export: 'levels',\n levels: [options.export],\n });\n }\n }\n\n // export === 'ungrouped' or nully:\n const ungrouped = ungroup(results, options?.addGroupKeys);\n return ungrouped as any;\n }) as GroupByFn<T, O, Keys, Opts>;\n // (_groupBy as any).tidyType = 'group-export';\n\n return _groupBy;\n}\n// convenient export option configs\ngroupBy.grouped = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'grouped' } as const);\ngroupBy.entries = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries' } as const);\ngroupBy.entriesObject = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'entries-object' } as const);\ngroupBy.object = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'object' } as const);\ngroupBy.map = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'map' } as const);\ngroupBy.keys = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'keys' } as const);\ngroupBy.values = (options?: Omit<GroupByOptions, 'export' | 'levels'>) =>\n ({ ...options, export: 'values' } as const);\ngroupBy.levels = (options?: Omit<GroupByOptions, 'export'>) =>\n ({ ...options, export: 'levels' } as const);\n\nfunction runFlow<T extends object>(\n items: Grouped<T>,\n fns?: TidyFn<any, any>[],\n addGroupKeys?: boolean\n) {\n let result: any = items;\n if (!fns?.length) return result;\n\n for (const fn of fns) {\n if (!fn) continue;\n\n // otherwise break it up and call it on each leaf set\n result = groupMap(result, (items, keys) => {\n // ensure we kept the group keys in the object\n // (necessary for e.g. summarize which may remove them)\n // snapshot keys since groupTraversal reuses the array\n const keysSnapshot = keys.slice();\n const context = { groupKeys: keysSnapshot };\n let leafItemsMapped = fn(items, context);\n if (addGroupKeys !== false) {\n // pre-filter keys once per group instead of per item\n const filteredKeys = keysSnapshot.filter(\n (key: any) => typeof key[0] !== 'function' && key[0] != null\n );\n leafItemsMapped = leafItemsMapped.map((item: T) =>\n assignGroupKeys(item, keysSnapshot, filteredKeys)\n );\n }\n\n return leafItemsMapped;\n });\n }\n\n return result;\n}\n\nfunction makeGrouped<T extends object>(\n items: T[],\n groupKeys: SingleOrArray<keyof T | ((d: T) => any)>\n): Grouped<T> {\n // convert string based keys to functions and keep the key name with the key value in a tuple\n const groupKeyFns = singleOrArray(groupKeys).map((key) => {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n // use a cache so we don't generate new keys for the same tuple\n const keyCache = new Map();\n return (d: T) => {\n const keyValue = keyFn(d);\n\n const keyValueOf = isObject(keyValue) ? keyValue.valueOf() : keyValue;\n // used cache tuple if available\n if (keyCache.has(keyValueOf)) {\n return keyCache.get(keyValueOf) as GroupKey;\n }\n\n const keyWithName = [key, keyValue];\n keyCache.set(keyValueOf, keyWithName);\n\n return keyWithName;\n };\n });\n\n const grouped = group(items, ...groupKeyFns);\n return grouped;\n}\n\n/**\n * flattens a grouped collection back to a simple array\n */\nfunction ungroup<T extends object>(\n grouped: Grouped<T>,\n addGroupKeys: boolean | undefined\n): T[] {\n // flatten the groups\n const items: T[] = [];\n\n groupTraversal(grouped, items, [], identity, (root, keys, values) => {\n // ensure we have group keys on items (in case runFlow didn't run)\n let valuesToAdd = values;\n if (addGroupKeys !== false) {\n // pre-filter keys once per group instead of per item\n const filteredKeys = keys.filter(\n (key: any) => typeof key[0] !== 'function' && key[0] != null\n );\n valuesToAdd = values.map((d) => assignGroupKeys(d, keys, filteredKeys));\n }\n root.push(...valuesToAdd);\n });\n\n return items;\n}\n\n// -----------------------------------------------------------------------\n// --- EXPORTS -----------------------------------------------------------\n// -----------------------------------------------------------------------\nconst defaultCompositeKey = (keys: any[]) => keys.join('/');\n\nfunction processFromGroupsOptions<T extends object>(options: GroupByOptions) {\n const {\n flat,\n single,\n mapLeaf = identity,\n mapLeaves = identity,\n addGroupKeys,\n } = options;\n let compositeKey: (keys: any[]) => string;\n if (options.flat) {\n compositeKey = options.compositeKey! ?? defaultCompositeKey;\n }\n\n const groupFn = (values: T[], keys: any[]) => {\n return single\n ? mapLeaf(\n addGroupKeys === false ? values[0] : assignGroupKeys(values[0], keys)\n )\n : mapLeaves(\n values.map((d) =>\n mapLeaf(addGroupKeys === false ? d : assignGroupKeys(d, keys))\n )\n );\n };\n\n const keyFn = flat\n ? (keys: GroupKey[]) => compositeKey(keys.map((d) => d[1]))\n : (keys: GroupKey[]) => keys[keys.length - 1][1];\n\n return { groupFn, keyFn };\n}\n\n// -- Levels -------------------------------------------------------------\nfunction exportLevels<T extends object>(\n grouped: Grouped<T>,\n options: GroupByOptions\n): any {\n type NestedEntries<T> = Array<[any, NestedEntries<T> | T[]]>;\n type NestedObject<T> = { [key: string]: NestedObject<T> | T[] };\n\n const { groupFn, keyFn } = processFromGroupsOptions(options);\n let { mapEntry = identity } = options;\n const { levels = ['entries'] } = options;\n\n const levelSpecs: LevelSpec[] = [];\n for (const levelOption of levels) {\n switch (levelOption) {\n // entries / entries-object -----------------------------------------\n case 'entries':\n case 'entries-object':\n case 'entries-obj' as any:\n case 'entriesObject' as any: {\n const levelMapEntry =\n (levelOption === 'entries-object' ||\n levelOption === ('entries-obj' as any) ||\n levelOption === ('entriesObject' as any)) &&\n options.mapEntry == null\n ? ([key, values]: any) => ({ key, values })\n : mapEntry;\n\n levelSpecs.push({\n id: 'entries',\n createEmptySubgroup: () => [],\n addSubgroup: (\n parentGrouped: NestedEntries<T>,\n newSubgroup: any,\n key: any,\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, newSubgroup], level));\n },\n\n addLeaf: (\n parentGrouped: NestedEntries<T>,\n key: any,\n values: T[],\n level: number\n ) => {\n parentGrouped.push(levelMapEntry([key, values], level));\n },\n });\n break;\n }\n // map -------------------------------------------------------------\n case 'map':\n levelSpecs.push({\n id: 'map',\n createEmptySubgroup: () => new Map(),\n addSubgroup: (\n parentGrouped: Map<any, any>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped.set(key, newSubgroup);\n },\n\n addLeaf: (parentGrouped: Map<any, any>, key: any, values: T[]) => {\n parentGrouped.set(key, values);\n },\n });\n break;\n\n // object ----------------------------------------------------------\n case 'object':\n levelSpecs.push({\n id: 'object',\n createEmptySubgroup: () => ({}),\n addSubgroup: (\n parentGrouped: NestedObject<T>,\n newSubgroup: any,\n key: any\n ) => {\n parentGrouped[key] = newSubgroup;\n },\n\n addLeaf: (parentGrouped: NestedObject<T>, key: any, values: T[]) => {\n parentGrouped[key] = values;\n },\n });\n break;\n\n // keys ------------------------------------------------------------\n case 'keys':\n levelSpecs.push({\n id: 'keys',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any, key: any) => {\n parentGrouped.push([key, newSubgroup]);\n },\n\n addLeaf: (parentGrouped: any, key: any) => {\n parentGrouped.push(key);\n },\n });\n break;\n\n // values ----------------------------------------------------------\n case 'values':\n levelSpecs.push({\n id: 'values',\n createEmptySubgroup: () => [],\n addSubgroup: (parentGrouped: any, newSubgroup: any) => {\n parentGrouped.push(newSubgroup);\n },\n\n addLeaf: (parentGrouped: any, key: any, values: T[]) => {\n parentGrouped.push(values);\n },\n });\n break;\n\n // custom ----------------------------------------------------------\n default: {\n // LevelSpec obj already\n if (typeof levelOption === 'object') {\n levelSpecs.push(levelOption);\n }\n }\n }\n }\n\n // add subgroup\n const addSubgroup = (parentGrouped: any, keys: any[], level: number): any => {\n if (options.flat) {\n return parentGrouped;\n }\n\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n const nextLevelSpec = levelSpecs[level + 1] ?? levelSpec;\n const newSubgroup = nextLevelSpec.createEmptySubgroup();\n levelSpec!.addSubgroup(parentGrouped, newSubgroup, keyFn(keys), level);\n return newSubgroup;\n };\n\n // add leaves\n const addLeaf = (\n parentGrouped: any,\n keys: any[],\n values: T[],\n level: number\n ) => {\n const levelSpec = levelSpecs[level] ?? levelSpecs[levelSpecs.length - 1];\n levelSpec!.addLeaf(\n parentGrouped,\n keyFn(keys),\n groupFn(values, keys),\n level\n );\n };\n\n const initialOutputObject = levelSpecs[0]!.createEmptySubgroup();\n return groupTraversal(grouped, initialOutputObject, [], addSubgroup, addLeaf);\n}\n"],"names":["groupMap","items","assignGroupKeys","singleOrArray","isObject","group","groupTraversal","identity"],"mappings":"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"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return d;
|
|
8
|
-
const keysObj = Object.fromEntries(keys.filter((key) => typeof key[0] !== "function"));
|
|
3
|
+
function assignGroupKeys(d, keys, filteredKeys) {
|
|
4
|
+
if (d == null || typeof d !== "object" || Array.isArray(d)) return d;
|
|
5
|
+
const validKeys = filteredKeys != null ? filteredKeys : keys.filter((key) => typeof key[0] !== "function" && key[0] != null);
|
|
6
|
+
const keysObj = Object.fromEntries(validKeys);
|
|
9
7
|
return Object.assign(keysObj, d);
|
|
10
8
|
}
|
|
11
9
|
|