@tidyjs/tidy 2.5.2 → 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/es/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":[],"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":["items"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
function assignGroupKeys(d, keys) {
|
|
2
|
-
if (d == null || typeof d !== "object" || Array.isArray(d))
|
|
3
|
-
|
|
4
|
-
const keysObj = Object.fromEntries(
|
|
1
|
+
function assignGroupKeys(d, keys, filteredKeys) {
|
|
2
|
+
if (d == null || typeof d !== "object" || Array.isArray(d)) return d;
|
|
3
|
+
const validKeys = filteredKeys != null ? filteredKeys : keys.filter((key) => typeof key[0] !== "function" && key[0] != null);
|
|
4
|
+
const keysObj = Object.fromEntries(validKeys);
|
|
5
5
|
return Object.assign(keysObj, d);
|
|
6
6
|
}
|
|
7
7
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assignGroupKeys.js","sources":["../../../src/helpers/assignGroupKeys.ts"],"sourcesContent":["import { GroupKey } from '../types';\n\n/**\n * Given an object and a set of group keys [[keyName, keyValue], ...]\n * set the keys as properties within the object: { [keyName]: keyValue, ... }\n * (creates a new object with these properties added)\n */\nexport function assignGroupKeys<T extends object>(d: T
|
|
1
|
+
{"version":3,"file":"assignGroupKeys.js","sources":["../../../src/helpers/assignGroupKeys.ts"],"sourcesContent":["import { GroupKey } from '../types';\n\n/**\n * Given an object and a set of group keys [[keyName, keyValue], ...]\n * set the keys as properties within the object: { [keyName]: keyValue, ... }\n * (creates a new object with these properties added)\n */\nexport function assignGroupKeys<T extends object>(\n d: T,\n keys: GroupKey[],\n filteredKeys?: GroupKey[]\n) {\n // abort if atypical input\n if (d == null || typeof d !== 'object' || Array.isArray(d)) return d;\n\n // use pre-filtered keys if provided, otherwise filter here\n const validKeys =\n filteredKeys ??\n keys.filter((key) => typeof key[0] !== 'function' && key[0] != null);\n\n // transform to { groupKey1: value, ... } excluding function group keys\n const keysObj = Object.fromEntries(validKeys);\n\n return Object.assign(keysObj, d);\n}\n"],"names":[],"mappings":"AAOgB,SAAA,eAAA,CACd,CACA,EAAA,IAAA,EACA,YACA,EAAA;AAEA,EAAI,IAAA,CAAA,IAAK,QAAQ,OAAO,CAAA,KAAM,YAAY,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA,EAAU,OAAA,CAAA,CAAA;AAGnE,EAAA,MAAM,SACJ,GAAA,YAAA,IAAA,IAAA,GAAA,YAAA,GACA,IAAK,CAAA,MAAA,CAAO,CAAC,GAAQ,KAAA,OAAO,GAAI,CAAA,CAAC,CAAM,KAAA,UAAA,IAAc,GAAI,CAAA,CAAC,KAAK,IAAI,CAAA,CAAA;AAGrE,EAAM,MAAA,OAAA,GAAU,MAAO,CAAA,WAAA,CAAY,SAAS,CAAA,CAAA;AAE5C,EAAO,OAAA,MAAA,CAAO,MAAO,CAAA,OAAA,EAAS,CAAC,CAAA,CAAA;AACjC;;;;"}
|
|
@@ -2,14 +2,14 @@ import { groupTraversal } from './groupTraversal.js';
|
|
|
2
2
|
|
|
3
3
|
function groupMap(grouped, groupFn, keyFn = (keys) => keys[keys.length - 1]) {
|
|
4
4
|
function addSubgroup(parentGrouped, keys) {
|
|
5
|
-
const subgroup = new Map();
|
|
5
|
+
const subgroup = /* @__PURE__ */ new Map();
|
|
6
6
|
parentGrouped.set(keyFn(keys), subgroup);
|
|
7
7
|
return subgroup;
|
|
8
8
|
}
|
|
9
9
|
function addLeaves(parentGrouped, keys, values) {
|
|
10
10
|
parentGrouped.set(keyFn(keys), groupFn(values, keys));
|
|
11
11
|
}
|
|
12
|
-
const outputGrouped = new Map();
|
|
12
|
+
const outputGrouped = /* @__PURE__ */ new Map();
|
|
13
13
|
groupTraversal(grouped, outputGrouped, [], addSubgroup, addLeaves);
|
|
14
14
|
return outputGrouped;
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupMap.js","sources":["../../../src/helpers/groupMap.ts"],"sourcesContent":["import { Grouped } from '../types';\nimport { groupTraversal } from './groupTraversal';\n\nexport function groupMap<T extends object, OutputT extends object = T>(\n grouped: Grouped<T>,\n groupFn: (items: T[], keys: any[]) => OutputT[],\n keyFn: (keys: any[]) => any = (keys) =>\n keys[\n keys.length - 1\n ] /* optional func to transform key based on all keys in map so far */\n): Grouped<OutputT> {\n function addSubgroup(parentGrouped: Grouped<OutputT>, keys: any[]) {\n const subgroup = new Map();\n parentGrouped.set(keyFn(keys), subgroup);\n return subgroup;\n }\n\n function addLeaves(\n parentGrouped: Grouped<OutputT>,\n keys: any[],\n values: T[]\n ) {\n parentGrouped.set(keyFn(keys), groupFn(values, keys));\n }\n\n const outputGrouped: Grouped<OutputT> = new Map();\n\n groupTraversal(grouped, outputGrouped, [], addSubgroup, addLeaves);\n\n return outputGrouped;\n}\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"groupMap.js","sources":["../../../src/helpers/groupMap.ts"],"sourcesContent":["import { Grouped } from '../types';\nimport { groupTraversal } from './groupTraversal';\n\nexport function groupMap<T extends object, OutputT extends object = T>(\n grouped: Grouped<T>,\n groupFn: (items: T[], keys: any[]) => OutputT[],\n keyFn: (keys: any[]) => any = (keys) =>\n keys[\n keys.length - 1\n ] /* optional func to transform key based on all keys in map so far */\n): Grouped<OutputT> {\n function addSubgroup(parentGrouped: Grouped<OutputT>, keys: any[]) {\n const subgroup = new Map();\n parentGrouped.set(keyFn(keys), subgroup);\n return subgroup;\n }\n\n function addLeaves(\n parentGrouped: Grouped<OutputT>,\n keys: any[],\n values: T[]\n ) {\n parentGrouped.set(keyFn(keys), groupFn(values, keys));\n }\n\n const outputGrouped: Grouped<OutputT> = new Map();\n\n groupTraversal(grouped, outputGrouped, [], addSubgroup, addLeaves);\n\n return outputGrouped;\n}\n"],"names":[],"mappings":";;AAGgB,SAAA,QAAA,CACd,OACA,EAAA,OAAA,EACA,KAA8B,GAAA,CAAC,SAC7B,IACE,CAAA,IAAA,CAAK,MAAS,GAAA,CAChB,CACgB,EAAA;AAClB,EAAS,SAAA,WAAA,CAAY,eAAiC,IAAa,EAAA;AACjE,IAAM,MAAA,QAAA,uBAAe,GAAI,EAAA,CAAA;AACzB,IAAA,aAAA,CAAc,GAAI,CAAA,KAAA,CAAM,IAAI,CAAA,EAAG,QAAQ,CAAA,CAAA;AACvC,IAAO,OAAA,QAAA,CAAA;AAAA,GACT;AAEA,EAAS,SAAA,SAAA,CACP,aACA,EAAA,IAAA,EACA,MACA,EAAA;AACA,IAAA,aAAA,CAAc,IAAI,KAAM,CAAA,IAAI,GAAG,OAAQ,CAAA,MAAA,EAAQ,IAAI,CAAC,CAAA,CAAA;AAAA,GACtD;AAEA,EAAM,MAAA,aAAA,uBAAsC,GAAI,EAAA,CAAA;AAEhD,EAAA,cAAA,CAAe,OAAS,EAAA,aAAA,EAAe,EAAC,EAAG,aAAa,SAAS,CAAA,CAAA;AAEjE,EAAO,OAAA,aAAA,CAAA;AACT;;;;"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
function groupTraversal(grouped, outputGrouped, keys, addSubgroup, addLeaves, level = 0) {
|
|
2
2
|
for (const [key, value] of grouped.entries()) {
|
|
3
|
-
|
|
3
|
+
keys.push(key);
|
|
4
4
|
if (value instanceof Map) {
|
|
5
|
-
const subgroup = addSubgroup(outputGrouped,
|
|
6
|
-
groupTraversal(value, subgroup,
|
|
5
|
+
const subgroup = addSubgroup(outputGrouped, keys, level);
|
|
6
|
+
groupTraversal(value, subgroup, keys, addSubgroup, addLeaves, level + 1);
|
|
7
7
|
} else {
|
|
8
|
-
addLeaves(outputGrouped,
|
|
8
|
+
addLeaves(outputGrouped, keys, value, level);
|
|
9
9
|
}
|
|
10
|
+
keys.pop();
|
|
10
11
|
}
|
|
11
12
|
return outputGrouped;
|
|
12
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupTraversal.js","sources":["../../../src/helpers/groupTraversal.ts"],"sourcesContent":["import { Grouped, Datum } from '../types';\n\n/**\n * Traverse the leaves of the grouped items and and run the\n * groupFn on them. Basically an in-order traversal. Can you\n * believe this is real and not part of a coding interview??\n */\nexport function groupTraversal<\n T extends object,\n T2 extends Datum = T,\n OutputType = Grouped<T2>\n>(\n grouped: Grouped<T>,\n outputGrouped: OutputType,\n keys: any[],\n addSubgroup: (root: OutputType, keys: any[], level: number) => OutputType,\n addLeaves: (root: OutputType, keys: any[], items: T[], level: number) => void,\n level: number = 0\n) {\n for (const [key, value] of grouped.entries()) {\n
|
|
1
|
+
{"version":3,"file":"groupTraversal.js","sources":["../../../src/helpers/groupTraversal.ts"],"sourcesContent":["import { Grouped, Datum } from '../types';\n\n/**\n * Traverse the leaves of the grouped items and and run the\n * groupFn on them. Basically an in-order traversal. Can you\n * believe this is real and not part of a coding interview??\n */\nexport function groupTraversal<\n T extends object,\n T2 extends Datum = T,\n OutputType = Grouped<T2>\n>(\n grouped: Grouped<T>,\n outputGrouped: OutputType,\n keys: any[],\n addSubgroup: (root: OutputType, keys: any[], level: number) => OutputType,\n addLeaves: (root: OutputType, keys: any[], items: T[], level: number) => void,\n level: number = 0\n) {\n for (const [key, value] of grouped.entries()) {\n keys.push(key);\n\n // internal node\n if (value instanceof Map) {\n const subgroup = addSubgroup(outputGrouped, keys, level);\n\n // recurse\n groupTraversal(value, subgroup, keys, addSubgroup, addLeaves, level + 1);\n } else {\n // leaf\n addLeaves(outputGrouped, keys, value, level);\n }\n\n keys.pop();\n }\n\n return outputGrouped;\n}\n"],"names":[],"mappings":"AAOO,SAAS,eAKd,OACA,EAAA,aAAA,EACA,MACA,WACA,EAAA,SAAA,EACA,QAAgB,CAChB,EAAA;AACA,EAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,CAAK,IAAA,OAAA,CAAQ,SAAW,EAAA;AAC5C,IAAA,IAAA,CAAK,KAAK,GAAG,CAAA,CAAA;AAGb,IAAA,IAAI,iBAAiB,GAAK,EAAA;AACxB,MAAA,MAAM,QAAW,GAAA,WAAA,CAAY,aAAe,EAAA,IAAA,EAAM,KAAK,CAAA,CAAA;AAGvD,MAAA,cAAA,CAAe,OAAO,QAAU,EAAA,IAAA,EAAM,WAAa,EAAA,SAAA,EAAW,QAAQ,CAAC,CAAA,CAAA;AAAA,KAClE,MAAA;AAEL,MAAU,SAAA,CAAA,aAAA,EAAe,IAAM,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AAAA,KAC7C;AAEA,IAAA,IAAA,CAAK,GAAI,EAAA,CAAA;AAAA,GACX;AAEA,EAAO,OAAA,aAAA,CAAA;AACT;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sources":["../../../src/helpers/identity.ts"],"sourcesContent":["export const identity = <T>(d: T): T => d;\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"identity.js","sources":["../../../src/helpers/identity.ts"],"sourcesContent":["export const identity = <T>(d: T): T => d;\n"],"names":[],"mappings":"AAAa,MAAA,QAAA,GAAW,CAAI,CAAY,KAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isObject.js","sources":["../../../src/helpers/isObject.ts"],"sourcesContent":["/**\n * Returns true if input is an object\n */\nexport function isObject(obj: any) {\n const type = typeof obj;\n return obj != null && (type === 'object' || type === 'function');\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"isObject.js","sources":["../../../src/helpers/isObject.ts"],"sourcesContent":["/**\n * Returns true if input is an object\n */\nexport function isObject(obj: any) {\n const type = typeof obj;\n return obj != null && (type === 'object' || type === 'function');\n}\n"],"names":[],"mappings":"AAGO,SAAS,SAAS,GAAU,EAAA;AACjC,EAAA,MAAM,OAAO,OAAO,GAAA,CAAA;AACpB,EAAA,OAAO,GAAO,IAAA,IAAA,KAAS,IAAS,KAAA,QAAA,IAAY,IAAS,KAAA,UAAA,CAAA,CAAA;AACvD;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keysFromItems.js","sources":["../../../src/helpers/keysFromItems.ts"],"sourcesContent":["/**\n * Helper to get keys from a collection of items.\n * For now, it naively just looks at the first item, but a more complete\n * solution involves looking at all of them (in case keys are omitted).\n * This isn't very efficient though, so perhaps there's a future where\n * the keys are stored sneakily on the object somewhere and that set\n * is updated after each tidy fn is called (if we can do it efficiently)\n *\n * Or perhaps this function can be memoized in a smart way where we don't\n * call it more than necessary?\n */\nexport function keysFromItems<T extends object>(items: T[]): (keyof T)[] {\n if (items.length < 1) return [];\n const keys = Object.keys(items[0]) as (keyof T)[];\n return keys;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keysFromItems.js","sources":["../../../src/helpers/keysFromItems.ts"],"sourcesContent":["/**\n * Helper to get keys from a collection of items.\n * For now, it naively just looks at the first item, but a more complete\n * solution involves looking at all of them (in case keys are omitted).\n * This isn't very efficient though, so perhaps there's a future where\n * the keys are stored sneakily on the object somewhere and that set\n * is updated after each tidy fn is called (if we can do it efficiently)\n *\n * Or perhaps this function can be memoized in a smart way where we don't\n * call it more than necessary?\n */\nexport function keysFromItems<T extends object>(items: T[]): (keyof T)[] {\n if (items.length < 1) return [];\n const keys = Object.keys(items[0]) as (keyof T)[];\n return keys;\n}\n"],"names":[],"mappings":"AAWO,SAAS,cAAgC,KAAyB,EAAA;AACvE,EAAA,IAAI,KAAM,CAAA,MAAA,GAAS,CAAG,EAAA,OAAO,EAAC,CAAA;AAC9B,EAAA,MAAM,IAAO,GAAA,MAAA,CAAO,IAAK,CAAA,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AACjC,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleOrArray.js","sources":["../../../src/helpers/singleOrArray.ts"],"sourcesContent":["export type SingleOrArray<T> = T | T[];\n\n/**\n * Given an arg that may or may not be an array, make it an array if it isn't one.\n */\nexport function singleOrArray<T>(d: SingleOrArray<T> | null | undefined): T[] {\n return d == null ? [] : Array.isArray(d) ? d : [d];\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"singleOrArray.js","sources":["../../../src/helpers/singleOrArray.ts"],"sourcesContent":["export type SingleOrArray<T> = T | T[];\n\n/**\n * Given an arg that may or may not be an array, make it an array if it isn't one.\n */\nexport function singleOrArray<T>(d: SingleOrArray<T> | null | undefined): T[] {\n return d == null ? [] : Array.isArray(d) ? d : [d];\n}\n"],"names":[],"mappings":"AAKO,SAAS,cAAiB,CAA6C,EAAA;AAC5E,EAAO,OAAA,CAAA,IAAK,IAAO,GAAA,EAAK,GAAA,KAAA,CAAM,QAAQ,CAAC,CAAA,GAAI,CAAI,GAAA,CAAC,CAAC,CAAA,CAAA;AACnD;;;;"}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
import { Adder
|
|
1
|
+
import { Adder } from 'd3-array';
|
|
2
2
|
|
|
3
3
|
function fcumsum(items, accessor) {
|
|
4
4
|
let sum = new Adder(), i = 0;
|
|
5
|
-
return Float64Array.from(
|
|
5
|
+
return Float64Array.from(
|
|
6
|
+
items,
|
|
7
|
+
// we do not actually need to coerce the Adder to number,
|
|
8
|
+
// as @Fil demonstrated here: https://github.com/pbeshai/tidy/pull/5
|
|
9
|
+
// so we can just tell typescript to be quiet.
|
|
10
|
+
(value) => sum.add(+(accessor(value, i++, items) || 0))
|
|
11
|
+
);
|
|
6
12
|
}
|
|
7
13
|
function mean(items, accessor) {
|
|
8
14
|
let n = 0;
|
|
15
|
+
const sum = new Adder();
|
|
9
16
|
for (let i = 0; i < items.length; ++i) {
|
|
10
17
|
const value = accessor(items[i], i, items);
|
|
11
18
|
if (+value === value) {
|
|
19
|
+
sum.add(+value);
|
|
12
20
|
n += 1;
|
|
13
21
|
}
|
|
14
22
|
}
|
|
15
|
-
return n ?
|
|
23
|
+
return n ? +sum / n : void 0;
|
|
16
24
|
}
|
|
17
25
|
|
|
18
26
|
export { fcumsum, mean };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summation.js","sources":["../../../src/helpers/summation.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"summation.js","sources":["../../../src/helpers/summation.ts"],"sourcesContent":["import { Adder } from 'd3-array';\n\n// See also https://observablehq.com/@fil/fcumsum\nexport function fcumsum<T>(\n items: T[],\n accessor: (element: T, i: number, array: Iterable<T>) => any\n): Float64Array {\n let sum = new Adder(),\n i = 0;\n\n return Float64Array.from(\n items,\n // we do not actually need to coerce the Adder to number,\n // as @Fil demonstrated here: https://github.com/pbeshai/tidy/pull/5\n // so we can just tell typescript to be quiet.\n (value: T): number =>\n sum.add(+(accessor(value, i++, items) || 0)) as unknown as number\n );\n}\n\nexport function mean<T>(\n items: T[],\n accessor: (element: T, i: number, array: Iterable<T>) => any\n): number | undefined {\n let n = 0;\n const sum = new Adder();\n for (let i = 0; i < items.length; ++i) {\n const value = accessor(items[i], i, items);\n // count it if we have a valid number\n if (+value === value) {\n sum.add(+value);\n n += 1;\n }\n }\n\n return n ? +sum / n : undefined;\n}\n"],"names":[],"mappings":";;AAGgB,SAAA,OAAA,CACd,OACA,QACc,EAAA;AACd,EAAA,IAAI,GAAM,GAAA,IAAI,KAAM,EAAA,EAClB,CAAI,GAAA,CAAA,CAAA;AAEN,EAAA,OAAO,YAAa,CAAA,IAAA;AAAA,IAClB,KAAA;AAAA;AAAA;AAAA;AAAA,IAIA,CAAC,KACC,KAAA,GAAA,CAAI,GAAI,CAAA,EAAE,SAAS,KAAO,EAAA,CAAA,EAAA,EAAK,KAAK,CAAA,IAAK,CAAE,CAAA,CAAA;AAAA,GAC/C,CAAA;AACF,CAAA;AAEgB,SAAA,IAAA,CACd,OACA,QACoB,EAAA;AACpB,EAAA,IAAI,CAAI,GAAA,CAAA,CAAA;AACR,EAAM,MAAA,GAAA,GAAM,IAAI,KAAM,EAAA,CAAA;AACtB,EAAA,KAAA,IAAS,IAAI,CAAG,EAAA,CAAA,GAAI,KAAM,CAAA,MAAA,EAAQ,EAAE,CAAG,EAAA;AACrC,IAAA,MAAM,QAAQ,QAAS,CAAA,KAAA,CAAM,CAAC,CAAA,EAAG,GAAG,KAAK,CAAA,CAAA;AAEzC,IAAI,IAAA,CAAC,UAAU,KAAO,EAAA;AACpB,MAAI,GAAA,CAAA,GAAA,CAAI,CAAC,KAAK,CAAA,CAAA;AACd,MAAK,CAAA,IAAA,CAAA,CAAA;AAAA,KACP;AAAA,GACF;AAEA,EAAO,OAAA,CAAA,GAAI,CAAC,GAAA,GAAM,CAAI,GAAA,KAAA,CAAA,CAAA;AACxB;;;;"}
|
package/dist/es/innerJoin.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
function autodetectByMap(itemsA, itemsB) {
|
|
2
|
-
if (itemsA.length === 0 || itemsB.length === 0)
|
|
3
|
-
return {};
|
|
2
|
+
if (itemsA.length === 0 || itemsB.length === 0) return {};
|
|
4
3
|
const keysA = Object.keys(itemsA[0]);
|
|
5
4
|
const keysB = Object.keys(itemsB[0]);
|
|
6
5
|
const byMap = {};
|
|
@@ -21,28 +20,54 @@ function makeByMap(by) {
|
|
|
21
20
|
} else if (typeof by === "object") {
|
|
22
21
|
return by;
|
|
23
22
|
}
|
|
24
|
-
return {[by]: by};
|
|
23
|
+
return { [by]: by };
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
const KEY_DELIMITER = "\0";
|
|
26
|
+
const NULL_SENTINEL = "N";
|
|
27
|
+
const UNDEF_SENTINEL = "U";
|
|
28
|
+
function serializeValue(v) {
|
|
29
|
+
if (v === null) return NULL_SENTINEL;
|
|
30
|
+
if (v === void 0) return UNDEF_SENTINEL;
|
|
31
|
+
return String(v);
|
|
32
|
+
}
|
|
33
|
+
function computeKey(row, keys) {
|
|
34
|
+
if (keys.length === 1) return serializeValue(row[keys[0]]);
|
|
35
|
+
let key = "";
|
|
36
|
+
for (let i = 0; i < keys.length; i++) {
|
|
37
|
+
if (i > 0) key += KEY_DELIMITER;
|
|
38
|
+
key += serializeValue(row[keys[i]]);
|
|
39
|
+
}
|
|
40
|
+
return key;
|
|
41
|
+
}
|
|
42
|
+
function buildJoinIndex(itemsToJoin, joinKeys) {
|
|
43
|
+
const index = /* @__PURE__ */ new Map();
|
|
44
|
+
for (const j of itemsToJoin) {
|
|
45
|
+
const key = computeKey(j, joinKeys);
|
|
46
|
+
let bucket = index.get(key);
|
|
47
|
+
if (bucket === void 0) {
|
|
48
|
+
bucket = [];
|
|
49
|
+
index.set(key, bucket);
|
|
31
50
|
}
|
|
51
|
+
bucket.push(j);
|
|
32
52
|
}
|
|
33
|
-
return
|
|
53
|
+
return index;
|
|
34
54
|
}
|
|
35
55
|
function innerJoin(itemsToJoin, options) {
|
|
36
56
|
const _innerJoin = (items) => {
|
|
37
57
|
const byMap = (options == null ? void 0 : options.by) == null ? autodetectByMap(items, itemsToJoin) : makeByMap(options.by);
|
|
58
|
+
const joinKeys = Object.keys(byMap);
|
|
59
|
+
const itemKeys = joinKeys.map((jKey) => byMap[jKey]);
|
|
60
|
+
const index = buildJoinIndex(itemsToJoin, joinKeys);
|
|
38
61
|
const joined = items.flatMap((d) => {
|
|
39
|
-
const
|
|
40
|
-
|
|
62
|
+
const key = computeKey(d, itemKeys);
|
|
63
|
+
const matches = index.get(key);
|
|
64
|
+
if (matches === void 0) return [];
|
|
65
|
+
return matches.map((j) => ({ ...d, ...j }));
|
|
41
66
|
});
|
|
42
67
|
return joined;
|
|
43
68
|
};
|
|
44
69
|
return _innerJoin;
|
|
45
70
|
}
|
|
46
71
|
|
|
47
|
-
export { autodetectByMap,
|
|
72
|
+
export { autodetectByMap, buildJoinIndex, computeKey, innerJoin, makeByMap };
|
|
48
73
|
//# sourceMappingURL=innerJoin.js.map
|
package/dist/es/innerJoin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"innerJoin.js","sources":["../../src/innerJoin.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"innerJoin.js","sources":["../../src/innerJoin.ts"],"sourcesContent":["import { TidyFn, Datum } from './types';\nimport { Merge } from './type-utils';\n\ntype ByMap<JoinT extends Datum, T extends Datum> = Partial<\n Record<keyof JoinT, keyof T>\n>;\n\nexport type JoinOptions<JoinT extends Datum, T extends Datum> = {\n by?: keyof T | (keyof T)[] | ByMap<JoinT, T>;\n};\n\n/**\n * Compares first two sets of items to find overlapping keys\n * Naively looks at first element... could cause problems if first\n * elements don't have all keys, but scanning each entire set seems\n * unnecessarily slow for most cases.\n */\nexport function autodetectByMap<A extends object, B extends object>(\n itemsA: A[],\n itemsB: B[]\n) {\n if (itemsA.length === 0 || itemsB.length === 0) return {};\n\n // intersection of shared keys\n const keysA = Object.keys(itemsA[0]);\n const keysB = Object.keys(itemsB[0]);\n\n // naive linear intersection, but we don't expect objects to have tons of keys\n // so it's probably fine.\n const byMap: any = {};\n for (const key of keysA) {\n if (keysB.includes(key)) {\n byMap[key] = key;\n }\n }\n\n return byMap;\n}\n\n// convert by option in to a map from JoinT to T key\nexport function makeByMap<T extends Datum, JoinT extends Datum>(\n by: JoinOptions<JoinT, T>['by']\n): ByMap<JoinT, T> {\n // convert by option in to a map from JoinT to T key\n if (Array.isArray(by)) {\n const byMap: ByMap<JoinT, T> = {};\n for (const key of by) {\n byMap[key as any] = key;\n }\n return byMap;\n } else if (typeof by === 'object') {\n return by;\n }\n return { [by as keyof JoinT]: by as keyof T } as ByMap<JoinT, T>;\n}\n\nexport function isMatch<T extends object, JoinT extends object>(\n d: T,\n j: JoinT,\n byMap: ByMap<JoinT, T>\n) {\n for (const jKey in byMap) {\n const dKey = byMap[jKey];\n if ((d[dKey as keyof T] as any) !== j[jKey as keyof JoinT]) {\n return false;\n }\n }\n return true;\n}\n\nconst KEY_DELIMITER = '\\x00';\nconst NULL_SENTINEL = '\\x01N';\nconst UNDEF_SENTINEL = '\\x01U';\n\nfunction serializeValue(v: any): string {\n if (v === null) return NULL_SENTINEL;\n if (v === undefined) return UNDEF_SENTINEL;\n return String(v);\n}\n\nexport function computeKey(row: any, keys: string[]): string {\n if (keys.length === 1) return serializeValue(row[keys[0]]);\n let key = '';\n for (let i = 0; i < keys.length; i++) {\n if (i > 0) key += KEY_DELIMITER;\n key += serializeValue(row[keys[i]]);\n }\n return key;\n}\n\nexport function buildJoinIndex<JoinT extends object>(\n itemsToJoin: JoinT[],\n joinKeys: string[]\n): Map<string, JoinT[]> {\n const index = new Map<string, JoinT[]>();\n for (const j of itemsToJoin) {\n const key = computeKey(j, joinKeys);\n let bucket = index.get(key);\n if (bucket === undefined) {\n bucket = [];\n index.set(key, bucket);\n }\n bucket.push(j);\n }\n return index;\n}\n\n/**\n * Performs an inner join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function innerJoin<T extends object, JoinT extends object>(\n itemsToJoin: JoinT[],\n options?: JoinOptions<JoinT, T> | null | undefined\n): TidyFn<T, Merge<T, JoinT>> {\n const _innerJoin: TidyFn<T, Merge<T, JoinT>> = (\n items: T[]\n ): Merge<T, JoinT>[] => {\n // convert by option in to a map from JoinT to T 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 const joined = items.flatMap((d: T) => {\n const key = computeKey(d, itemKeys);\n const matches = index.get(key);\n if (matches === undefined) return [];\n return matches.map((j: JoinT) => ({ ...d, ...j }));\n });\n\n return joined as Merge<T, JoinT>[];\n };\n return _innerJoin;\n}\n"],"names":[],"mappings":"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"}
|
package/dist/es/item/rate.js
CHANGED
|
@@ -3,14 +3,13 @@ import { rate as rate$1 } from '../math/math.js';
|
|
|
3
3
|
function rate(numerator, denominator, options) {
|
|
4
4
|
const numeratorFn = typeof numerator === "function" ? numerator : (d) => d[numerator];
|
|
5
5
|
const denominatorFn = typeof denominator === "function" ? denominator : (d) => d[denominator];
|
|
6
|
-
const {predicate, allowDivideByZero} = options != null ? options : {};
|
|
6
|
+
const { predicate, allowDivideByZero } = options != null ? options : {};
|
|
7
7
|
return predicate == null ? (d, index, array) => {
|
|
8
8
|
const denom = denominatorFn(d, index, array);
|
|
9
9
|
const numer = numeratorFn(d, index, array);
|
|
10
10
|
return rate$1(numer, denom, allowDivideByZero);
|
|
11
11
|
} : (d, index, array) => {
|
|
12
|
-
if (!predicate(d, index, array))
|
|
13
|
-
return void 0;
|
|
12
|
+
if (!predicate(d, index, array)) return void 0;
|
|
14
13
|
const denom = denominatorFn(d, index, array);
|
|
15
14
|
const numer = numeratorFn(d, index, array);
|
|
16
15
|
return rate$1(numer, denom, allowDivideByZero);
|
package/dist/es/item/rate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate.js","sources":["../../../src/item/rate.ts"],"sourcesContent":["import { rate as mathRate } from '../math/math';\n\ntype RateOptions<T> = {\n predicate?: (d: T, index: number, array: Iterable<T>) => boolean;\n allowDivideByZero?: boolean;\n};\n\n/**\n * Returns a function that computes a rate (numerator / denominator), setting the value to\n * 0 if denominator = 0 and numerator = 0.\n */\nexport function rate<T extends object>(\n numerator: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n denominator: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n options?: RateOptions<T>\n) {\n const numeratorFn =\n typeof numerator === 'function'\n ? numerator\n : (d: T) =>
|
|
1
|
+
{"version":3,"file":"rate.js","sources":["../../../src/item/rate.ts"],"sourcesContent":["import { rate as mathRate } from '../math/math';\n\ntype RateOptions<T> = {\n predicate?: (d: T, index: number, array: Iterable<T>) => boolean;\n allowDivideByZero?: boolean;\n};\n\n/**\n * Returns a function that computes a rate (numerator / denominator), setting the value to\n * 0 if denominator = 0 and numerator = 0.\n */\nexport function rate<T extends object>(\n numerator: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n denominator: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n options?: RateOptions<T>\n) {\n const numeratorFn =\n typeof numerator === 'function'\n ? numerator\n : (d: T) => d[numerator] as unknown as number;\n const denominatorFn =\n typeof denominator === 'function'\n ? denominator\n : (d: T) => d[denominator] as unknown as number;\n\n const { predicate, allowDivideByZero } = options ?? {};\n return predicate == null\n ? (d: T, index: number, array: Iterable<T>) => {\n const denom = denominatorFn(d, index, array);\n const numer = numeratorFn(d, index, array);\n return mathRate(numer, denom, allowDivideByZero);\n }\n : (d: T, index: number, array: Iterable<T>) => {\n if (!predicate(d, index, array)) return undefined;\n\n const denom = denominatorFn(d, index, array);\n const numer = numeratorFn(d, index, array);\n return mathRate(numer, denom, allowDivideByZero);\n };\n}\n"],"names":["mathRate"],"mappings":";;AAWgB,SAAA,IAAA,CACd,SACA,EAAA,WAAA,EACA,OACA,EAAA;AACA,EAAM,MAAA,WAAA,GACJ,OAAO,SAAc,KAAA,UAAA,GACjB,YACA,CAAC,CAAA,KAAS,EAAE,SAAS,CAAA,CAAA;AAC3B,EAAM,MAAA,aAAA,GACJ,OAAO,WAAgB,KAAA,UAAA,GACnB,cACA,CAAC,CAAA,KAAS,EAAE,WAAW,CAAA,CAAA;AAE7B,EAAA,MAAM,EAAE,SAAA,EAAW,iBAAkB,EAAA,GAAI,4BAAW,EAAC,CAAA;AACrD,EAAA,OAAO,SAAa,IAAA,IAAA,GAChB,CAAC,CAAA,EAAM,OAAe,KAAuB,KAAA;AAC3C,IAAA,MAAM,KAAQ,GAAA,aAAA,CAAc,CAAG,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AAC3C,IAAA,MAAM,KAAQ,GAAA,WAAA,CAAY,CAAG,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AACzC,IAAO,OAAAA,MAAA,CAAS,KAAO,EAAA,KAAA,EAAO,iBAAiB,CAAA,CAAA;AAAA,GAEjD,GAAA,CAAC,CAAM,EAAA,KAAA,EAAe,KAAuB,KAAA;AAC3C,IAAA,IAAI,CAAC,SAAU,CAAA,CAAA,EAAG,KAAO,EAAA,KAAK,GAAU,OAAA,KAAA,CAAA,CAAA;AAExC,IAAA,MAAM,KAAQ,GAAA,aAAA,CAAc,CAAG,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AAC3C,IAAA,MAAM,KAAQ,GAAA,WAAA,CAAY,CAAG,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AACzC,IAAO,OAAAA,MAAA,CAAS,KAAO,EAAA,KAAA,EAAO,iBAAiB,CAAA,CAAA;AAAA,GACjD,CAAA;AACN;;;;"}
|
package/dist/es/leftJoin.js
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import { autodetectByMap, makeByMap,
|
|
1
|
+
import { autodetectByMap, makeByMap, buildJoinIndex, computeKey } from './innerJoin.js';
|
|
2
2
|
|
|
3
3
|
function leftJoin(itemsToJoin, options) {
|
|
4
4
|
const _leftJoin = (items) => {
|
|
5
|
-
if (!itemsToJoin.length)
|
|
6
|
-
return items;
|
|
5
|
+
if (!itemsToJoin.length) return items;
|
|
7
6
|
const byMap = (options == null ? void 0 : options.by) == null ? autodetectByMap(items, itemsToJoin) : makeByMap(options.by);
|
|
7
|
+
const joinKeys = Object.keys(byMap);
|
|
8
|
+
const itemKeys = joinKeys.map((jKey) => byMap[jKey]);
|
|
9
|
+
const index = buildJoinIndex(itemsToJoin, joinKeys);
|
|
8
10
|
const joinObjectKeys = Object.keys(itemsToJoin[0]);
|
|
9
11
|
const joined = items.flatMap((d) => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
const key = computeKey(d, itemKeys);
|
|
13
|
+
const matches = index.get(key);
|
|
14
|
+
if (matches !== void 0) {
|
|
15
|
+
return matches.map((j) => ({ ...d, ...j }));
|
|
13
16
|
}
|
|
14
|
-
const undefinedFill = Object.fromEntries(
|
|
15
|
-
|
|
17
|
+
const undefinedFill = Object.fromEntries(
|
|
18
|
+
joinObjectKeys.filter((key2) => d[key2] == null).map((key2) => [key2, void 0])
|
|
19
|
+
);
|
|
20
|
+
return { ...d, ...undefinedFill };
|
|
16
21
|
});
|
|
17
22
|
return joined;
|
|
18
23
|
};
|
package/dist/es/leftJoin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leftJoin.js","sources":["../../src/leftJoin.ts"],"sourcesContent":["import { Datum, TidyFn } from './types';\nimport {
|
|
1
|
+
{"version":3,"file":"leftJoin.js","sources":["../../src/leftJoin.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 left join on two collections\n * @param itemsToJoin The rows/items to be appended to end of collection\n */\nexport function leftJoin<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 _leftJoin: TidyFn<T, Merge<T, Partial<JoinT>>> = (\n items: T[]\n ): Merge<T, Partial<JoinT>>[] => {\n if (!itemsToJoin.length) return items 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 // 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 if (matches !== undefined) {\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 return joined;\n };\n return _leftJoin;\n}\n"],"names":["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;AAGhC,IAAM,MAAA,KAAA,GAAA,CACJ,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,EAAA,KAAM,IACX,GAAA,eAAA,CAAgB,OAAO,WAAW,CAAA,GAClC,SAAU,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,GAAQ,cAAe,CAAA,WAAA,EAAa,QAAQ,CAAA,CAAA;AAIlD,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,GAAM,UAAW,CAAA,CAAA,EAAG,QAAQ,CAAA,CAAA;AAClC,MAAM,MAAA,OAAA,GAAU,KAAM,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAC7B,MAAA,IAAI,YAAY,KAAW,CAAA,EAAA;AACzB,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,CAACA,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;AAED,IAAO,OAAA,MAAA,CAAA;AAAA,GACT,CAAA;AACA,EAAO,OAAA,SAAA,CAAA;AACT;;;;"}
|
package/dist/es/map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.js","sources":["../../src/map.ts"],"sourcesContent":["import { TidyFn } from './types';\n\n/**\n * Maps items\n * @param mapFn Maps items from one form to another\n */\nexport function map<T extends object, OutputT>(\n mapFn: (item: T, index: number, array: T[]) => OutputT\n): TidyFn<T, OutputT> {\n const _map: TidyFn<T, OutputT> = (items: T[]) => items.map(mapFn);\n return _map;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"map.js","sources":["../../src/map.ts"],"sourcesContent":["import { TidyFn } from './types';\n\n/**\n * Maps items\n * @param mapFn Maps items from one form to another\n */\nexport function map<T extends object, OutputT>(\n mapFn: (item: T, index: number, array: T[]) => OutputT\n): TidyFn<T, OutputT> {\n const _map: TidyFn<T, OutputT> = (items: T[]) => items.map(mapFn);\n return _map;\n}\n"],"names":[],"mappings":"AAMO,SAAS,IACd,KACoB,EAAA;AACpB,EAAA,MAAM,IAA2B,GAAA,CAAC,KAAe,KAAA,KAAA,CAAM,IAAI,KAAK,CAAA,CAAA;AAChE,EAAO,OAAA,IAAA,CAAA;AACT;;;;"}
|
package/dist/es/math/math.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.js","sources":["../../../src/math/math.ts"],"sourcesContent":["/** Tidy math helpers */\n\n/** Compute a fraction while handling common edge cases */\nexport function rate(\n numerator: number | null | undefined,\n denominator: number | null | undefined,\n allowDivideByZero?: boolean\n): number | undefined {\n return numerator == null || denominator == null\n ? undefined\n : denominator === 0 && numerator === 0\n ? 0\n : !allowDivideByZero && denominator === 0\n ? undefined\n : numerator / denominator;\n}\n\nexport function subtract(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) - (b ?? 0)\n : undefined\n : a - b;\n}\n\nexport function add(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) + (b ?? 0)\n : undefined\n : a + b;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"math.js","sources":["../../../src/math/math.ts"],"sourcesContent":["/** Tidy math helpers */\n\n/** Compute a fraction while handling common edge cases */\nexport function rate(\n numerator: number | null | undefined,\n denominator: number | null | undefined,\n allowDivideByZero?: boolean\n): number | undefined {\n return numerator == null || denominator == null\n ? undefined\n : denominator === 0 && numerator === 0\n ? 0\n : !allowDivideByZero && denominator === 0\n ? undefined\n : numerator / denominator;\n}\n\nexport function subtract(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) - (b ?? 0)\n : undefined\n : a - b;\n}\n\nexport function add(\n a: number | null | undefined,\n b: number | null | undefined,\n nullyZero?: boolean\n) {\n return a == null || b == null\n ? nullyZero\n ? (a ?? 0) + (b ?? 0)\n : undefined\n : a + b;\n}\n"],"names":[],"mappings":"AAGgB,SAAA,IAAA,CACd,SACA,EAAA,WAAA,EACA,iBACoB,EAAA;AACpB,EAAA,OAAO,SAAa,IAAA,IAAA,IAAQ,WAAe,IAAA,IAAA,GACvC,SACA,WAAgB,KAAA,CAAA,IAAK,SAAc,KAAA,CAAA,GACnC,IACA,CAAC,iBAAA,IAAqB,WAAgB,KAAA,CAAA,GACtC,SACA,SAAY,GAAA,WAAA,CAAA;AAClB,CAAA;AAEgB,SAAA,QAAA,CACd,CACA,EAAA,CAAA,EACA,SACA,EAAA;AACA,EAAO,OAAA,CAAA,IAAK,IAAQ,IAAA,CAAA,IAAK,IACrB,GAAA,SAAA,GAAA,CACG,gBAAK,CAAM,KAAA,CAAA,IAAA,IAAA,GAAA,CAAA,GAAK,CACjB,CAAA,GAAA,KAAA,CAAA,GACF,CAAI,GAAA,CAAA,CAAA;AACV,CAAA;AAEgB,SAAA,GAAA,CACd,CACA,EAAA,CAAA,EACA,SACA,EAAA;AACA,EAAO,OAAA,CAAA,IAAK,IAAQ,IAAA,CAAA,IAAK,IACrB,GAAA,SAAA,GAAA,CACG,gBAAK,CAAM,KAAA,CAAA,IAAA,IAAA,GAAA,CAAA,GAAK,CACjB,CAAA,GAAA,KAAA,CAAA,GACF,CAAI,GAAA,CAAA,CAAA;AACV;;;;"}
|
package/dist/es/mutate.js
CHANGED
package/dist/es/mutate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutate.js","sources":["../../src/mutate.ts"],"sourcesContent":["import { TidyFn, NonFunctionValue, Key } from './types';\nimport {
|
|
1
|
+
{"version":3,"file":"mutate.js","sources":["../../src/mutate.ts"],"sourcesContent":["import { TidyFn, NonFunctionValue, Key } from './types';\nimport { Prettify, Merge } from './type-utils';\n\ntype MutateSpecValue<T, O = any> =\n | ((item: T, index: number, array: Iterable<T>) => O)\n | NonFunctionValue;\nexport type MutateSpec<T> = Record<Key, MutateSpecValue<T>>;\nexport type ResolvedObj<Obj extends Record<Key, MutateSpecValue<any>>> = {\n [K in keyof Obj]: Obj[K] extends (...args: any) => any\n ? ReturnType<Obj[K]> extends any[]\n ? ReturnType<Obj[K]>[number]\n : ReturnType<Obj[K]>\n : Obj[K];\n};\n\ntype Mutated<T extends object, MSpec extends MutateSpec<T>> = Merge<\n ResolvedObj<MSpec>,\n T\n>;\n\ntype Compute<T> = Prettify<T>;\n\n/**\n * Mutates items, one item at a time. For mutating across multiple items,\n * use mutateWithSummary.\n * @param mutateSpec\n */\nexport function mutate<T extends object, MSpec extends MutateSpec<T>>(\n mutateSpec: MSpec\n): TidyFn<T, Compute<Mutated<T, MSpec>>> {\n type MutatedT = Mutated<T, MSpec>;\n // use Compute for better intellisense (reveals all keys in obj)\n const _mutate: TidyFn<T, Compute<MutatedT>> = (\n items: T[]\n ): Compute<MutatedT>[] => {\n // create the base items to merge mutated values into\n // note we start with the original array so when we pass it as the third argument\n // to a mutate function, you get the values that have been changed so far\n const mutatedItems: MutatedT[] = items.map((d) => ({ ...d })) as MutatedT[];\n\n // we can update each item completely one at a time, since mutate doesn't\n // support looking across items. Use mutateWithSummary for that.\n let i = 0;\n for (const mutatedItem of mutatedItems) {\n for (const key in mutateSpec) {\n // get the mutated value for this item (either run the fn or use the constant)\n const mutateSpecValue = mutateSpec[key];\n const mutatedResult =\n typeof mutateSpecValue === 'function'\n ? mutateSpecValue(mutatedItem as T, i, mutatedItems as T[])\n : mutateSpecValue;\n\n mutatedItem[key as any] = mutatedResult;\n }\n\n ++i;\n }\n\n return mutatedItems as Compute<MutatedT>[];\n };\n\n return _mutate;\n}\n"],"names":[],"mappings":"AA2BO,SAAS,OACd,UACuC,EAAA;AAGvC,EAAM,MAAA,OAAA,GAAwC,CAC5C,KACwB,KAAA;AAIxB,IAAM,MAAA,YAAA,GAA2B,MAAM,GAAI,CAAA,CAAC,OAAO,EAAE,GAAG,GAAI,CAAA,CAAA,CAAA;AAI5D,IAAA,IAAI,CAAI,GAAA,CAAA,CAAA;AACR,IAAA,KAAA,MAAW,eAAe,YAAc,EAAA;AACtC,MAAA,KAAA,MAAW,OAAO,UAAY,EAAA;AAE5B,QAAM,MAAA,eAAA,GAAkB,WAAW,GAAG,CAAA,CAAA;AACtC,QAAM,MAAA,aAAA,GACJ,OAAO,eAAoB,KAAA,UAAA,GACvB,gBAAgB,WAAkB,EAAA,CAAA,EAAG,YAAmB,CACxD,GAAA,eAAA,CAAA;AAEN,QAAA,WAAA,CAAY,GAAU,CAAI,GAAA,aAAA,CAAA;AAAA,OAC5B;AAEA,MAAE,EAAA,CAAA,CAAA;AAAA,KACJ;AAEA,IAAO,OAAA,YAAA,CAAA;AAAA,GACT,CAAA;AAEA,EAAO,OAAA,OAAA,CAAA;AACT;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
function mutateWithSummary(mutateSpec) {
|
|
2
2
|
const _mutate = (items) => {
|
|
3
|
-
const mutatedItems = items.map((d) => ({...d}));
|
|
3
|
+
const mutatedItems = items.map((d) => ({ ...d }));
|
|
4
4
|
for (const key in mutateSpec) {
|
|
5
5
|
const mutateSpecValue = mutateSpec[key];
|
|
6
6
|
const mutatedResult = typeof mutateSpecValue === "function" ? mutateSpecValue(mutatedItems) : mutateSpecValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutateWithSummary.js","sources":["../../src/mutateWithSummary.ts"],"sourcesContent":["import { TidyFn, NonFunctionValue, Key } from './types';\nimport {
|
|
1
|
+
{"version":3,"file":"mutateWithSummary.js","sources":["../../src/mutateWithSummary.ts"],"sourcesContent":["import { TidyFn, NonFunctionValue, Key } from './types';\nimport { Prettify } from './type-utils';\n\ntype MutateSpecValue<T, O = any> = ((items: T[]) => O[] | O) | NonFunctionValue;\nexport type MutateSummarySpec<T> = Record<Key, MutateSpecValue<T>>;\nexport type ResolvedObj<Obj extends Record<Key, MutateSpecValue<any>>> = {\n [K in keyof Obj]: Obj[K] extends (...args: any) => any\n ? ReturnType<Obj[K]> extends any[]\n ? ReturnType<Obj[K]>[number]\n : ReturnType<Obj[K]> extends Float64Array\n ? number\n : ReturnType<Obj[K]>\n : Obj[K];\n};\n\ntype Mutated<T, MSpec extends MutateSummarySpec<T>> = T & ResolvedObj<MSpec>;\n\ntype Compute<T> = Prettify<T>;\n\n/**\n * Mutates items, looking at multiple items at a time to enable summarization.\n * For simpler, item by item mutations, use mutate.\n * @param mutateSpec\n */\nexport function mutateWithSummary<\n T extends object,\n MSpec extends MutateSummarySpec<T>\n>(mutateSpec: MSpec): TidyFn<T, Compute<Mutated<T, MSpec>>> {\n type MutatedT = Mutated<T, MSpec>;\n // use Compute for better intellisense (reveals all keys in obj)\n const _mutate: TidyFn<T, Compute<MutatedT>> = (\n items: T[]\n ): Compute<MutatedT>[] => {\n // create the base items to merge mutated values into\n const mutatedItems: MutatedT[] = items.map((d) => ({ ...d })) as MutatedT[];\n\n // create vectors for each mutated value\n for (const key in mutateSpec) {\n // convert individual values to a vector of the same value\n // this allows mutate functions to return single numbers and still work\n const mutateSpecValue = mutateSpec[key];\n const mutatedResult =\n typeof mutateSpecValue === 'function'\n ? mutateSpecValue(mutatedItems)\n : mutateSpecValue;\n const mutatedVector =\n mutatedResult?.[Symbol.iterator] && typeof mutatedResult !== 'string'\n ? mutatedResult\n : items.map(() => mutatedResult);\n\n // merge the mutated vector into the mutated items\n let i = -1;\n for (const mutatedItem of mutatedItems) {\n mutatedItem[key as keyof MutatedT] = mutatedVector[++i];\n }\n }\n\n return mutatedItems as Compute<MutatedT>[];\n };\n\n return _mutate;\n}\n"],"names":[],"mappings":"AAwBO,SAAS,kBAGd,UAA0D,EAAA;AAG1D,EAAM,MAAA,OAAA,GAAwC,CAC5C,KACwB,KAAA;AAExB,IAAM,MAAA,YAAA,GAA2B,MAAM,GAAI,CAAA,CAAC,OAAO,EAAE,GAAG,GAAI,CAAA,CAAA,CAAA;AAG5D,IAAA,KAAA,MAAW,OAAO,UAAY,EAAA;AAG5B,MAAM,MAAA,eAAA,GAAkB,WAAW,GAAG,CAAA,CAAA;AACtC,MAAA,MAAM,gBACJ,OAAO,eAAA,KAAoB,UACvB,GAAA,eAAA,CAAgB,YAAY,CAC5B,GAAA,eAAA,CAAA;AACN,MAAM,MAAA,aAAA,GAAA,CACJ,aAAgB,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,aAAA,CAAA,MAAA,CAAO,QAAa,CAAA,KAAA,OAAO,aAAkB,KAAA,QAAA,GACzD,aACA,GAAA,KAAA,CAAM,GAAI,CAAA,MAAM,aAAa,CAAA,CAAA;AAGnC,MAAA,IAAI,CAAI,GAAA,CAAA,CAAA,CAAA;AACR,MAAA,KAAA,MAAW,eAAe,YAAc,EAAA;AACtC,QAAA,WAAA,CAAY,GAAqB,CAAA,GAAI,aAAc,CAAA,EAAE,CAAC,CAAA,CAAA;AAAA,OACxD;AAAA,KACF;AAEA,IAAO,OAAA,YAAA,CAAA;AAAA,GACT,CAAA;AAEA,EAAO,OAAA,OAAA,CAAA;AACT;;;;"}
|