@tidyjs/tidy 2.4.5 → 2.5.1
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/groupBy.js.map +1 -1
- package/dist/es/index.js +1 -0
- package/dist/es/index.js.map +1 -1
- package/dist/es/item/rate.js +7 -7
- package/dist/es/item/rate.js.map +1 -1
- package/dist/es/mutate.js +5 -5
- package/dist/es/mutate.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 +5 -1
- package/dist/es/summary/n.js.map +1 -1
- package/dist/es/summary/nDistinct.js +2 -1
- package/dist/es/summary/nDistinct.js.map +1 -1
- package/dist/es/summary/sum.js +7 -2
- package/dist/es/summary/sum.js.map +1 -1
- package/dist/es/summary/variance.js.map +1 -1
- package/dist/es/total.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 +4 -3
- package/dist/es/vector/roll.js.map +1 -1
- package/dist/es/vector/rowNumber.js +10 -0
- package/dist/es/vector/rowNumber.js.map +1 -0
- package/dist/lib/groupBy.js.map +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/item/rate.js +7 -7
- package/dist/lib/item/rate.js.map +1 -1
- package/dist/lib/mutate.js +5 -5
- package/dist/lib/mutate.js.map +1 -1
- package/dist/lib/summary/deviation.js.map +1 -1
- package/dist/lib/summary/first.js.map +1 -1
- package/dist/lib/summary/last.js.map +1 -1
- package/dist/lib/summary/max.js.map +1 -1
- package/dist/lib/summary/mean.js.map +1 -1
- package/dist/lib/summary/meanRate.js.map +1 -1
- package/dist/lib/summary/median.js.map +1 -1
- package/dist/lib/summary/min.js.map +1 -1
- package/dist/lib/summary/n.js +5 -1
- package/dist/lib/summary/n.js.map +1 -1
- package/dist/lib/summary/nDistinct.js +2 -1
- package/dist/lib/summary/nDistinct.js.map +1 -1
- package/dist/lib/summary/sum.js +7 -2
- package/dist/lib/summary/sum.js.map +1 -1
- package/dist/lib/summary/variance.js.map +1 -1
- package/dist/lib/total.js.map +1 -1
- package/dist/lib/vector/cumsum.js.map +1 -1
- package/dist/lib/vector/lag.js +1 -1
- package/dist/lib/vector/lag.js.map +1 -1
- package/dist/lib/vector/lead.js +1 -1
- package/dist/lib/vector/lead.js.map +1 -1
- package/dist/lib/vector/roll.js +4 -3
- package/dist/lib/vector/roll.js.map +1 -1
- package/dist/lib/vector/rowNumber.js +14 -0
- package/dist/lib/vector/rowNumber.js.map +1 -0
- package/dist/tidy.d.ts +893 -32
- package/dist/umd/tidy.js +41 -21
- 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 +2 -2
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 | undefined\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 | undefined\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, 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, 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, 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, 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, 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, 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, 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, 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>, Opts extends GroupByOptions>(groupKeys: Keys, options?: Opts): GroupByFn<T, T, Keys, Opts>;\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 { 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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"}
|
package/dist/es/index.js
CHANGED
|
@@ -32,6 +32,7 @@ export { cumsum } from './vector/cumsum.js';
|
|
|
32
32
|
export { roll } from './vector/roll.js';
|
|
33
33
|
export { lag } from './vector/lag.js';
|
|
34
34
|
export { lead } from './vector/lead.js';
|
|
35
|
+
export { rowNumber } from './vector/rowNumber.js';
|
|
35
36
|
export { sum } from './summary/sum.js';
|
|
36
37
|
export { min } from './summary/min.js';
|
|
37
38
|
export { max } from './summary/max.js';
|
package/dist/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/es/item/rate.js
CHANGED
|
@@ -4,15 +4,15 @@ 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
6
|
const {predicate, allowDivideByZero} = options != null ? options : {};
|
|
7
|
-
return predicate == null ? (d) => {
|
|
8
|
-
const denom = denominatorFn(d);
|
|
9
|
-
const numer = numeratorFn(d);
|
|
7
|
+
return predicate == null ? (d, index, array) => {
|
|
8
|
+
const denom = denominatorFn(d, index, array);
|
|
9
|
+
const numer = numeratorFn(d, index, array);
|
|
10
10
|
return rate$1(numer, denom, allowDivideByZero);
|
|
11
|
-
} : (d) => {
|
|
12
|
-
if (!predicate(d))
|
|
11
|
+
} : (d, index, array) => {
|
|
12
|
+
if (!predicate(d, index, array))
|
|
13
13
|
return void 0;
|
|
14
|
-
const denom = denominatorFn(d);
|
|
15
|
-
const numer = numeratorFn(d);
|
|
14
|
+
const denom = denominatorFn(d, index, array);
|
|
15
|
+
const numer = numeratorFn(d, index, array);
|
|
16
16
|
return rate$1(numer, denom, allowDivideByZero);
|
|
17
17
|
};
|
|
18
18
|
}
|
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) => 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) => number),\n denominator: keyof T | ((d: 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) => {\n const denom = denominatorFn(d);\n const numer = numeratorFn(d);\n return mathRate(numer, denom, allowDivideByZero);\n }\n : (d: T) => {\n if (!predicate(d)) return undefined;\n\n const denom = denominatorFn(d);\n const numer = numeratorFn(d);\n return mathRate(numer, denom, allowDivideByZero);\n };\n}\n"],"names":["mathRate"],"mappings":";;cAYE,WACA,aACA;AAEA,QAAM,cACJ,OAAO,cAAc,aACjB,YACA,CAAC,MAAU,EAAE;AACnB,QAAM,gBACJ,OAAO,gBAAgB,aACnB,cACA,CAAC,MAAU,EAAE;AAEnB,QAAM,CAAE,WAAW,qBAAsB,4BAAW;AACpD,SAAO,aAAa,OAChB,CAAC;
|
|
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":";;cAYE,WACA,aACA;AAEA,QAAM,cACJ,OAAO,cAAc,aACjB,YACA,CAAC,MAAU,EAAE;AACnB,QAAM,gBACJ,OAAO,gBAAgB,aACnB,cACA,CAAC,MAAU,EAAE;AAEnB,QAAM,CAAE,WAAW,qBAAsB,4BAAW;AACpD,SAAO,aAAa,OAChB,CAAC,GAAM,OAAe;AACpB,UAAM,QAAQ,cAAc,GAAG,OAAO;AACtC,UAAM,QAAQ,YAAY,GAAG,OAAO;AACpC,WAAOA,OAAS,OAAO,OAAO;AAAA,MAEhC,CAAC,GAAM,OAAe;AACpB,QAAI,CAAC,UAAU,GAAG,OAAO;AAAQ,aAAO;AAExC,UAAM,QAAQ,cAAc,GAAG,OAAO;AACtC,UAAM,QAAQ,YAAY,GAAG,OAAO;AACpC,WAAOA,OAAS,OAAO,OAAO;AAAA;AAAA;;;;"}
|
package/dist/es/mutate.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
function mutate(mutateSpec) {
|
|
2
2
|
const _mutate = (items) => {
|
|
3
|
-
const mutatedItems =
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const mutatedItems = items.map((d) => ({...d}));
|
|
4
|
+
let i = 0;
|
|
5
|
+
for (const mutatedItem of mutatedItems) {
|
|
6
6
|
for (const key in mutateSpec) {
|
|
7
7
|
const mutateSpecValue = mutateSpec[key];
|
|
8
|
-
const mutatedResult = typeof mutateSpecValue === "function" ? mutateSpecValue(mutatedItem) : mutateSpecValue;
|
|
8
|
+
const mutatedResult = typeof mutateSpecValue === "function" ? mutateSpecValue(mutatedItem, i, mutatedItems) : mutateSpecValue;
|
|
9
9
|
mutatedItem[key] = mutatedResult;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
++i;
|
|
12
12
|
}
|
|
13
13
|
return mutatedItems;
|
|
14
14
|
};
|
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 { A } from 'ts-toolbelt';\n\ntype MutateSpecValue<T, O = any>
|
|
1
|
+
{"version":3,"file":"mutate.js","sources":["../../src/mutate.ts"],"sourcesContent":["import { TidyFn, NonFunctionValue, Key } from './types';\nimport { A, O } from 'ts-toolbelt';\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>> = O.Merge<\n ResolvedObj<MSpec>,\n T\n>;\n\ntype Compute<T> = A.Compute<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":"gBA4BE;AAIA,QAAM,UAAwC,CAC5C;AAKA,UAAM,eAA2B,MAAM,IAAI,CAAC,WAAY;AAIxD,QAAI,IAAI;AACR,eAAW,eAAe;AACxB,iBAAW,OAAO;AAEhB,cAAM,kBAAkB,WAAW;AACnC,cAAM,gBACJ,OAAO,oBAAoB,aACvB,gBAAgB,aAAkB,GAAG,gBACrC;AAEN,oBAAY,OAAc;AAAA;AAG5B,QAAE;AAAA;AAGJ,WAAO;AAAA;AAGT,SAAO;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviation.js","sources":["../../../src/summary/deviation.ts"],"sourcesContent":["import { deviation as d3deviation } from 'd3-array';\n\n/**\n * Returns a function that computes the deviation over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function deviation<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3deviation(items, keyFn);\n}\n"],"names":["d3deviation"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"deviation.js","sources":["../../../src/summary/deviation.ts"],"sourcesContent":["import { deviation as d3deviation } from 'd3-array';\n\n/**\n * Returns a function that computes the deviation over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function deviation<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3deviation(items, keyFn);\n}\n"],"names":["d3deviation"],"mappings":";;mBAOE;AAEA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAEjD,SAAO,CAAC,UAAeA,YAAY,OAAO;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"first.js","sources":["../../../src/summary/first.ts"],"sourcesContent":["/**\n * Returns a function that returns the first value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function first<T extends object>(key: keyof T | ((d: T) =>
|
|
1
|
+
{"version":3,"file":"first.js","sources":["../../../src/summary/first.ts"],"sourcesContent":["/**\n * Returns a function that returns the first value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function first<T extends object>(key: keyof T | ((d: T) => any)) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) => (items.length ? keyFn(items[0]) : undefined);\n}\n"],"names":[],"mappings":"eAIwC;AACtC,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;AAE5D,SAAO,CAAC,UAAgB,MAAM,SAAS,MAAM,MAAM,MAAM;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"last.js","sources":["../../../src/summary/last.ts"],"sourcesContent":["/**\n * Returns a function that returns the last value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function last<T extends object>(key: keyof T | ((d: T) =>
|
|
1
|
+
{"version":3,"file":"last.js","sources":["../../../src/summary/last.ts"],"sourcesContent":["/**\n * Returns a function that returns the last value for the specified key\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function last<T extends object>(key: keyof T | ((d: T) => any)) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) =>\n items.length ? keyFn(items[items.length - 1]) : undefined;\n}\n"],"names":[],"mappings":"cAIuC;AACrC,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;AAE5D,SAAO,CAAC,UACN,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,MAAM;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"max.js","sources":["../../../src/summary/max.ts"],"sourcesContent":["import { max as d3max } from 'd3-array';\n\n/**\n * Returns a function that computes the max over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function max<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3max(items, keyFn);\n}\n"],"names":["d3max"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"max.js","sources":["../../../src/summary/max.ts"],"sourcesContent":["import { max as d3max } from 'd3-array';\n\n/**\n * Returns a function that computes the max over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function max<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3max(items, keyFn);\n}\n"],"names":["d3max"],"mappings":";;aAOE;AAEA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAEjD,SAAO,CAAC,UAAeA,MAAM,OAAO;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mean.js","sources":["../../../src/summary/mean.ts"],"sourcesContent":["import { mean as meanInternal } from '../helpers/summation';\n\n/**\n * Returns a function that computes the mean over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function mean<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => meanInternal(items, keyFn);\n}\n"],"names":["meanInternal"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"mean.js","sources":["../../../src/summary/mean.ts"],"sourcesContent":["import { mean as meanInternal } from '../helpers/summation';\n\n/**\n * Returns a function that computes the mean over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function mean<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => meanInternal(items, keyFn);\n}\n"],"names":["meanInternal"],"mappings":";;cAOE;AAEA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAEjD,SAAO,CAAC,UAAeA,OAAa,OAAO;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meanRate.js","sources":["../../../src/summary/meanRate.ts"],"sourcesContent":["import { fsum } from 'd3-array';\nimport { rate } from '../math/math';\n\n/**\n * Returns a function that computes the mean of a rate over an array of items\n * @param numerator A string key of the object or an accessor converting the object to a number\n * @param denominator A string key of the object or an accessor converting the object to a number\n */\nexport function meanRate<T extends object>(\n numerator: keyof T | ((d: T) => number),\n denominator: keyof T | ((d: T) => number)\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 return (items: T[]) => {\n const numerator = fsum(items, numeratorFn);\n const denominator = fsum(items, denominatorFn);\n return rate(numerator, denominator);\n };\n}\n"],"names":[],"mappings":";;;kBASE,WACA;AAEA,QAAM,cACJ,OAAO,cAAc,aACjB,YACA,CAAC,MAAU,EAAE;AACnB,QAAM,gBACJ,OAAO,gBAAgB,aACnB,cACA,CAAC,MAAU,EAAE;AAEnB,SAAO,CAAC;AACN,UAAM,aAAY,KAAK,OAAO;AAC9B,UAAM,eAAc,KAAK,OAAO;AAChC,WAAO,KAAK,YAAW;AAAA;AAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"meanRate.js","sources":["../../../src/summary/meanRate.ts"],"sourcesContent":["import { fsum } from 'd3-array';\nimport { rate } from '../math/math';\n\n/**\n * Returns a function that computes the mean of a rate over an array of items\n * @param numerator A string key of the object or an accessor converting the object to a number\n * @param denominator A string key of the object or an accessor converting the object to a number\n */\nexport function meanRate<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) {\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 return (items: T[]) => {\n const numerator = fsum(items, numeratorFn);\n const denominator = fsum(items, denominatorFn);\n return rate(numerator, denominator);\n };\n}\n"],"names":[],"mappings":";;;kBASE,WACA;AAEA,QAAM,cACJ,OAAO,cAAc,aACjB,YACA,CAAC,MAAU,EAAE;AACnB,QAAM,gBACJ,OAAO,gBAAgB,aACnB,cACA,CAAC,MAAU,EAAE;AAEnB,SAAO,CAAC;AACN,UAAM,aAAY,KAAK,OAAO;AAC9B,UAAM,eAAc,KAAK,OAAO;AAChC,WAAO,KAAK,YAAW;AAAA;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"median.js","sources":["../../../src/summary/median.ts"],"sourcesContent":["import { median as d3median } from 'd3-array';\n\n/**\n * Returns a function that computes the median over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function median<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3median(items, keyFn);\n}\n"],"names":["d3median"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"median.js","sources":["../../../src/summary/median.ts"],"sourcesContent":["import { median as d3median } from 'd3-array';\n\n/**\n * Returns a function that computes the median over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function median<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3median(items, keyFn);\n}\n"],"names":["d3median"],"mappings":";;gBAOE;AAEA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAEjD,SAAO,CAAC,UAAeA,SAAS,OAAO;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"min.js","sources":["../../../src/summary/min.ts"],"sourcesContent":["import { min as d3min } from 'd3-array';\n\n/**\n * Returns a function that computes the min over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function min<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3min(items, keyFn);\n}\n"],"names":["d3min"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"min.js","sources":["../../../src/summary/min.ts"],"sourcesContent":["import { min as d3min } from 'd3-array';\n\n/**\n * Returns a function that computes the min over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function min<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3min(items, keyFn);\n}\n"],"names":["d3min"],"mappings":";;aAOE;AAEA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAEjD,SAAO,CAAC,UAAeA,MAAM,OAAO;AAAA;;;;"}
|
package/dist/es/summary/n.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
function n() {
|
|
1
|
+
function n(options) {
|
|
2
|
+
if (options == null ? void 0 : options.predicate) {
|
|
3
|
+
const predicate = options.predicate;
|
|
4
|
+
return (items) => items.reduce((n2, d, i) => predicate(d, i, items) ? n2 + 1 : n2, 0);
|
|
5
|
+
}
|
|
2
6
|
return (items) => items.length;
|
|
3
7
|
}
|
|
4
8
|
|
package/dist/es/summary/n.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"n.js","sources":["../../../src/summary/n.ts"],"sourcesContent":["/**\n * Returns a function that computes the count over an array of items\n */\nexport function n() {\n return (items:
|
|
1
|
+
{"version":3,"file":"n.js","sources":["../../../src/summary/n.ts"],"sourcesContent":["type NOptions<T> = {\n predicate?: (d: T, index: number, array: Iterable<T>) => boolean;\n};\n\n/**\n * Returns a function that computes the count over an array of items\n */\nexport function n<T>(options?: NOptions<T>) {\n if (options?.predicate) {\n const predicate = options.predicate;\n return (items: T[]) =>\n items.reduce((n, d, i) => (predicate(d, i, items) ? n + 1 : n), 0);\n }\n\n return (items: T[]) => items.length;\n}\n"],"names":[],"mappings":"WAOqB;AACnB,MAAI,mCAAS;AACX,UAAM,YAAY,QAAQ;AAC1B,WAAO,CAAC,UACN,MAAM,OAAO,CAAC,IAAG,GAAG,MAAO,UAAU,GAAG,GAAG,SAAS,KAAI,IAAI,IAAI;AAAA;AAGpE,SAAO,CAAC,UAAe,MAAM;AAAA;;;;"}
|
|
@@ -3,8 +3,9 @@ function nDistinct(key, options = {}) {
|
|
|
3
3
|
return (items) => {
|
|
4
4
|
const uniques = new Map();
|
|
5
5
|
let count = 0;
|
|
6
|
+
let i = 0;
|
|
6
7
|
for (const item of items) {
|
|
7
|
-
const value = keyFn(item);
|
|
8
|
+
const value = keyFn(item, i++, items);
|
|
8
9
|
if (!uniques.has(value)) {
|
|
9
10
|
if (!options.includeUndefined && value === void 0 || options.includeNull === false && value === null) {
|
|
10
11
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nDistinct.js","sources":["../../../src/summary/nDistinct.ts"],"sourcesContent":["/**\n * Returns a function that computes the distinct count for a key\n * over an array of items. By default it counts nulls but not undefined\n */\nexport function nDistinct<T extends object>(\n key: keyof T | ((d: T) => any),\n options: { includeNull?: boolean; includeUndefined?: boolean } = {}\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) => {\n const uniques = new Map();\n let count = 0;\n\n for (const item of items) {\n const value = keyFn(item);\n\n if (!uniques.has(value)) {\n // default includes null but not undefined\n if (\n (!options.includeUndefined && value === undefined) ||\n (options.includeNull === false && value === null)\n ) {\n continue;\n }\n\n count += 1;\n uniques.set(value, true);\n }\n }\n\n return count;\n };\n}\n"],"names":[],"mappings":"mBAKE,KACA,UAAiE;AAEjE,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;AAE5D,SAAO,CAAC;AACN,UAAM,UAAU,IAAI;AACpB,QAAI,QAAQ;AAEZ,eAAW,QAAQ;AACjB,YAAM,QAAQ,MAAM;
|
|
1
|
+
{"version":3,"file":"nDistinct.js","sources":["../../../src/summary/nDistinct.ts"],"sourcesContent":["/**\n * Returns a function that computes the distinct count for a key\n * over an array of items. By default it counts nulls but not undefined\n */\nexport function nDistinct<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => any),\n options: { includeNull?: boolean; includeUndefined?: boolean } = {}\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n return (items: T[]) => {\n const uniques = new Map();\n let count = 0;\n\n let i = 0;\n for (const item of items) {\n const value = keyFn(item, i++, items);\n\n if (!uniques.has(value)) {\n // default includes null but not undefined\n if (\n (!options.includeUndefined && value === undefined) ||\n (options.includeNull === false && value === null)\n ) {\n continue;\n }\n\n count += 1;\n uniques.set(value, true);\n }\n }\n\n return count;\n };\n}\n"],"names":[],"mappings":"mBAKE,KACA,UAAiE;AAEjE,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;AAE5D,SAAO,CAAC;AACN,UAAM,UAAU,IAAI;AACpB,QAAI,QAAQ;AAEZ,QAAI,IAAI;AACR,eAAW,QAAQ;AACjB,YAAM,QAAQ,MAAM,MAAM,KAAK;AAE/B,UAAI,CAAC,QAAQ,IAAI;AAEf,YACG,CAAC,QAAQ,oBAAoB,UAAU,UACvC,QAAQ,gBAAgB,SAAS,UAAU;AAE5C;AAAA;AAGF,iBAAS;AACT,gBAAQ,IAAI,OAAO;AAAA;AAAA;AAIvB,WAAO;AAAA;AAAA;;;;"}
|
package/dist/es/summary/sum.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { fsum } from 'd3-array';
|
|
2
2
|
|
|
3
|
-
function sum(key) {
|
|
4
|
-
|
|
3
|
+
function sum(key, options) {
|
|
4
|
+
let keyFn = typeof key === "function" ? key : (d) => d[key];
|
|
5
|
+
if (options == null ? void 0 : options.predicate) {
|
|
6
|
+
const originalKeyFn = keyFn;
|
|
7
|
+
const predicate = options.predicate;
|
|
8
|
+
keyFn = (d, index, array) => predicate(d, index, array) ? originalKeyFn(d, index, array) : 0;
|
|
9
|
+
}
|
|
5
10
|
return (items) => fsum(items, keyFn);
|
|
6
11
|
}
|
|
7
12
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sum.js","sources":["../../../src/summary/sum.ts"],"sourcesContent":["import { fsum } from 'd3-array';\n\n/**\n * Returns a function that computes the sum over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function sum<T extends object>(key: keyof T | ((d: T) => number)) {\n
|
|
1
|
+
{"version":3,"file":"sum.js","sources":["../../../src/summary/sum.ts"],"sourcesContent":["import { fsum } from 'd3-array';\n\ntype SumOptions<T> = {\n predicate?: (d: T, index: number, array: Iterable<T>) => boolean;\n};\n\n/**\n * Returns a function that computes the sum over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function sum<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number),\n options?: SumOptions<T>\n) {\n let keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n if (options?.predicate) {\n const originalKeyFn = keyFn;\n const predicate = options.predicate;\n keyFn = (d: T, index: number, array: Iterable<T>) =>\n predicate(d, index, array) ? originalKeyFn(d, index, array) : 0;\n }\n\n return (items: T[]) => fsum(items, keyFn);\n}\n"],"names":[],"mappings":";;aAWE,KACA;AAEA,MAAI,QACF,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAEjD,MAAI,mCAAS;AACX,UAAM,gBAAgB;AACtB,UAAM,YAAY,QAAQ;AAC1B,YAAQ,CAAC,GAAM,OAAe,UAC5B,UAAU,GAAG,OAAO,SAAS,cAAc,GAAG,OAAO,SAAS;AAAA;AAGlE,SAAO,CAAC,UAAe,KAAK,OAAO;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variance.js","sources":["../../../src/summary/variance.ts"],"sourcesContent":["import { variance as d3variance } from 'd3-array';\n\n/**\n * Returns a function that computes the variance over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function variance<T extends object>(key: keyof T | ((d: T) => number)) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3variance(items, keyFn);\n}\n"],"names":["d3variance"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"variance.js","sources":["../../../src/summary/variance.ts"],"sourcesContent":["import { variance as d3variance } from 'd3-array';\n\n/**\n * Returns a function that computes the variance over an array of items\n * @param key A string key of the object or an accessor converting the object to a number\n */\nexport function variance<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => number)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n return (items: T[]) => d3variance(items, keyFn);\n}\n"],"names":["d3variance"],"mappings":";;kBAOE;AAEA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAEjD,SAAO,CAAC,UAAeA,WAAW,OAAO;AAAA;;;;"}
|
package/dist/es/total.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"total.js","sources":["../../src/total.ts"],"sourcesContent":["import { mutate, MutateSpec } from './mutate';\nimport {\n SummarizeSpec,\n summarize,\n summarizeAll,\n summarizeAt,\n summarizeIf,\n SummaryKeyFn,\n} from './summarize';\nimport { TidyFn, Vector } from './types';\n\n/**\n * Adds a summarized total row\n */\nexport function total<\n T extends object,\n SummarizedSpec extends SummarizeSpec<T> = SummarizeSpec<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summarizeSpec: SummarizedSpec, mutateSpec: MutSpec): TidyFn<T> {\n const _total: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarize<T, SummarizedSpec>(summarizeSpec)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _total;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAll<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAll: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAll<T, F>(summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalAll;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalIf<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(\n predicateFn: (vector: Vector<T>) => boolean,\n summaryFn: F,\n mutateSpec: MutSpec\n): TidyFn<T> {\n const _totalIf: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeIf<T, F>(predicateFn, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalIf;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAt<\n T extends object,\n Keys extends (keyof T)[],\n F extends SummaryKeyFn<T, Keys[number]>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(keys: Keys, summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAt: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAt<T, Keys, F>(keys, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]);\n return [...items, ...mutated];\n };\n\n return _totalAt;\n}\n"],"names":[],"mappings":";;;eAkBE,eAA+B;AAC/B,QAAM,SAAuB,CAAC;AAC5B,UAAM,aAAa,UAA6B,eAAe;AAC/D,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;kBAYP,WAAc;AACd,QAAM,YAA0B,CAAC;AAC/B,UAAM,aAAa,aAAmB,WAAW;AACjD,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;iBAaP,aACA,WACA;AAEA,QAAM,WAAyB,CAAC;AAC9B,UAAM,aAAa,YAAkB,aAAa,WAAW;AAC7D,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;iBAaP,MAAY,WAAc;AAC1B,QAAM,WAAyB,CAAC;AAC9B,UAAM,aAAa,YAAwB,MAAM,WAAW;AAC5D,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"total.js","sources":["../../src/total.ts"],"sourcesContent":["import { mutate, MutateSpec } from './mutate';\nimport {\n SummarizeSpec,\n summarize,\n summarizeAll,\n summarizeAt,\n summarizeIf,\n SummaryKeyFn,\n} from './summarize';\nimport { TidyFn, Vector } from './types';\n\n/**\n * Adds a summarized total row\n */\nexport function total<\n T extends object,\n SummarizedSpec extends SummarizeSpec<T> = SummarizeSpec<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summarizeSpec: SummarizedSpec, mutateSpec: MutSpec): TidyFn<T> {\n const _total: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarize<T, SummarizedSpec>(summarizeSpec)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]) as T[];\n return [...items, ...mutated];\n };\n\n return _total;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAll<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAll: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAll<T, F>(summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]) as T[];\n return [...items, ...mutated];\n };\n\n return _totalAll;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalIf<\n T extends object,\n F extends SummaryKeyFn<T>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(\n predicateFn: (vector: Vector<T>) => boolean,\n summaryFn: F,\n mutateSpec: MutSpec\n): TidyFn<T> {\n const _totalIf: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeIf<T, F>(predicateFn, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]) as T[];\n return [...items, ...mutated];\n };\n\n return _totalIf;\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Adds a summarized total row\n */\nexport function totalAt<\n T extends object,\n Keys extends (keyof T)[],\n F extends SummaryKeyFn<T, Keys[number]>,\n MutSpec extends MutateSpec<T> = MutateSpec<T>\n>(keys: Keys, summaryFn: F, mutateSpec: MutSpec): TidyFn<T> {\n const _totalAt: TidyFn<T, T> = (items: T[]): T[] => {\n const summarized = summarizeAt<T, Keys, F>(keys, summaryFn)(items);\n const mutated = mutate<T, MutSpec>(mutateSpec)(summarized as T[]) as T[];\n return [...items, ...mutated];\n };\n\n return _totalAt;\n}\n"],"names":[],"mappings":";;;eAkBE,eAA+B;AAC/B,QAAM,SAAuB,CAAC;AAC5B,UAAM,aAAa,UAA6B,eAAe;AAC/D,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;kBAYP,WAAc;AACd,QAAM,YAA0B,CAAC;AAC/B,UAAM,aAAa,aAAmB,WAAW;AACjD,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;iBAaP,aACA,WACA;AAEA,QAAM,WAAyB,CAAC;AAC9B,UAAM,aAAa,YAAkB,aAAa,WAAW;AAC7D,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;iBAaP,MAAY,WAAc;AAC1B,QAAM,WAAyB,CAAC;AAC9B,UAAM,aAAa,YAAwB,MAAM,WAAW;AAC5D,UAAM,UAAU,OAAmB,YAAY;AAC/C,WAAO,CAAC,GAAG,OAAO,GAAG;AAAA;AAGvB,SAAO;AAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cumsum.js","sources":["../../../src/vector/cumsum.ts"],"sourcesContent":["import { fcumsum } from '../helpers/summation';\n\nexport function cumsum<T extends object>(\n key
|
|
1
|
+
{"version":3,"file":"cumsum.js","sources":["../../../src/vector/cumsum.ts"],"sourcesContent":["import { fcumsum } from '../helpers/summation';\n\nexport function cumsum<T extends object>(\n key:\n | keyof T\n | ((d: T, index: number, array: Iterable<T>) => number | null | undefined)\n) {\n const keyFn =\n typeof key === 'function' ? key : (d: T) => (d[key] as unknown) as number;\n\n // note returns Float64Array not a normal array\n return (items: T[]) => fcumsum(items, keyFn);\n}\n"],"names":[],"mappings":";;gBAGE;AAIA,QAAM,QACJ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAU,EAAE;AAGjD,SAAO,CAAC,UAAe,QAAQ,OAAO;AAAA;;;;"}
|
package/dist/es/vector/lag.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lag.js","sources":["../../../src/vector/lag.ts"],"sourcesContent":["type LagOptions = {\n /** Number of positions to lag by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a function that lags a vector by a specified offset (n). Useful for\n * finding previous values to compute deltas with later.\n * @param key The key or accessor to lag\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lag<T extends object>(\n key: keyof T | ((d: T) => any),\n options?: LagOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items:
|
|
1
|
+
{"version":3,"file":"lag.js","sources":["../../../src/vector/lag.ts"],"sourcesContent":["type LagOptions = {\n /** Number of positions to lag by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a function that lags a vector by a specified offset (n). Useful for\n * finding previous values to compute deltas with later.\n * @param key The key or accessor to lag\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lag<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => any),\n options?: LagOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items: T[]) => {\n return items.map((_, i) => {\n const lagItem = items[i - n];\n return lagItem == null ? defaultValue : keyFn(lagItem, i, items);\n });\n };\n}\n"],"names":[],"mappings":"aAcE,KACA;AAEA,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;AAE5D,QAAM,CAAE,IAAI,GAAG,SAAS,gBAAiB,4BAAW;AAEpD,SAAO,CAAC;AACN,WAAO,MAAM,IAAI,CAAC,GAAG;AACnB,YAAM,UAAU,MAAM,IAAI;AAC1B,aAAO,WAAW,OAAO,eAAe,MAAM,SAAS,GAAG;AAAA;AAAA;AAAA;;;;"}
|
package/dist/es/vector/lead.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lead.js","sources":["../../../src/vector/lead.ts"],"sourcesContent":["type LeadOptions = {\n /** Number of positions to lead by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a functions that leads a vector by a specified offset (n). Useful for\n * finding next values for computing deltas with.\n * @param key The key or accessor to lead\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lead<T extends object>(\n key: keyof T | ((d: T) => any),\n options?: LeadOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items:
|
|
1
|
+
{"version":3,"file":"lead.js","sources":["../../../src/vector/lead.ts"],"sourcesContent":["type LeadOptions = {\n /** Number of positions to lead by (default: 1) */\n n?: number;\n /** The default value for non-existent rows. */\n default?: any;\n};\n\n/**\n * Returns a functions that leads a vector by a specified offset (n). Useful for\n * finding next values for computing deltas with.\n * @param key The key or accessor to lead\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function lead<T extends object>(\n key: keyof T | ((d: T, index: number, array: Iterable<T>) => any),\n options?: LeadOptions | undefined | null\n) {\n const keyFn = typeof key === 'function' ? key : (d: T) => d[key];\n\n const { n = 1, default: defaultValue } = options ?? {};\n\n return (items: T[]) => {\n return items.map((_, i) => {\n const leadItem = items[i + n];\n return leadItem == null ? defaultValue : keyFn(leadItem, i, items);\n });\n };\n}\n"],"names":[],"mappings":"cAcE,KACA;AAEA,QAAM,QAAQ,OAAO,QAAQ,aAAa,MAAM,CAAC,MAAS,EAAE;AAE5D,QAAM,CAAE,IAAI,GAAG,SAAS,gBAAiB,4BAAW;AAEpD,SAAO,CAAC;AACN,WAAO,MAAM,IAAI,CAAC,GAAG;AACnB,YAAM,WAAW,MAAM,IAAI;AAC3B,aAAO,YAAY,OAAO,eAAe,MAAM,UAAU,GAAG;AAAA;AAAA;AAAA;;;;"}
|
package/dist/es/vector/roll.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
function roll(width, rollFn, options) {
|
|
2
|
-
const {partial = false} = options != null ? options : {};
|
|
2
|
+
const {partial = false, align = "right"} = options != null ? options : {};
|
|
3
|
+
const halfWidth = Math.floor(width / 2);
|
|
3
4
|
return (items) => {
|
|
4
5
|
return items.map((_, i) => {
|
|
5
|
-
const endIndex = i;
|
|
6
|
-
if (!partial && endIndex - width + 1 < 0) {
|
|
6
|
+
const endIndex = align === "right" ? i : align === "center" ? i + halfWidth : i + width - 1;
|
|
7
|
+
if (!partial && (endIndex - width + 1 < 0 || endIndex >= items.length)) {
|
|
7
8
|
return void 0;
|
|
8
9
|
}
|
|
9
10
|
const startIndex = Math.max(0, endIndex - width + 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roll.js","sources":["../../../src/vector/roll.ts"],"sourcesContent":["type RollOptions = {\n partial?: boolean;\n};\n\n/**\n * Returns a function that computes the a rolling value (e.g. moving average) by\n * applying a function over a window of data\n * @param width The size of the window\n * @param rollFn The function to apply to the window (should reduce to a single value)\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function roll<T extends object>(\n width: number,\n rollFn: (itemsInWindow: T[], endIndex: number) => any,\n options?: RollOptions | undefined | null\n) {\n const { partial = false } = options ?? {};\n\n return (items: any[]) => {\n return items.map((_, i) => {\n const endIndex
|
|
1
|
+
{"version":3,"file":"roll.js","sources":["../../../src/vector/roll.ts"],"sourcesContent":["type RollOptions = {\n partial?: boolean;\n /** which direction the window is aligned to (default: right, looking back)\n * - right: current row is the last item [1,2,**3**]\n * - left: current row is the first item [**1**,2,3]\n * - center: current row is the center item [1,**2**,3]\n */\n align?: 'left' | 'center' | 'right';\n};\n\n/**\n * Returns a function that computes the a rolling value (e.g. moving average) by\n * applying a function over a window of data\n * @param width The size of the window\n * @param rollFn The function to apply to the window (should reduce to a single value)\n * @param options Options to configure roll. e.g. whether to run on partial windows.\n */\nexport function roll<T extends object>(\n width: number,\n rollFn: (itemsInWindow: T[], endIndex: number) => any,\n options?: RollOptions | undefined | null\n) {\n const { partial = false, align = 'right' } = options ?? {};\n\n const halfWidth = Math.floor(width / 2);\n\n return (items: any[]) => {\n return items.map((_, i) => {\n const endIndex =\n align === 'right'\n ? i\n : align === 'center'\n ? i + halfWidth\n : i + width - 1;\n\n // partial window and we don't allow partial computation, return undefined\n if (!partial && (endIndex - width + 1 < 0 || endIndex >= items.length)) {\n return undefined;\n }\n\n const startIndex = Math.max(0, endIndex - width + 1);\n const itemsInWindow = items.slice(startIndex, endIndex + 1);\n\n // reduce them to a single value\n return rollFn(itemsInWindow, endIndex);\n });\n };\n}\n"],"names":[],"mappings":"cAkBE,OACA,QACA;AAEA,QAAM,CAAE,UAAU,OAAO,QAAQ,WAAY,4BAAW;AAExD,QAAM,YAAY,KAAK,MAAM,QAAQ;AAErC,SAAO,CAAC;AACN,WAAO,MAAM,IAAI,CAAC,GAAG;AACnB,YAAM,WACJ,UAAU,UACN,IACA,UAAU,WACV,IAAI,YACJ,IAAI,QAAQ;AAGlB,UAAI,CAAC,uBAAuB,QAAQ,IAAI,KAAK,YAAY,MAAM;AAC7D,eAAO;AAAA;AAGT,YAAM,aAAa,KAAK,IAAI,GAAG,WAAW,QAAQ;AAClD,YAAM,gBAAgB,MAAM,MAAM,YAAY,WAAW;AAGzD,aAAO,OAAO,eAAe;AAAA;AAAA;AAAA;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function rowNumber(options) {
|
|
2
|
+
var _a;
|
|
3
|
+
const startAt = (_a = options == null ? void 0 : options.startAt) != null ? _a : 0;
|
|
4
|
+
return (items) => {
|
|
5
|
+
return items.map((_, i) => i + startAt);
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export { rowNumber };
|
|
10
|
+
//# sourceMappingURL=rowNumber.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rowNumber.js","sources":["../../../src/vector/rowNumber.ts"],"sourcesContent":["type RowNumberOptions = {\n /** what to start row numbers at, default is 0 */\n startAt?: number;\n};\n\n/**\n * Returns a vector of row numbers, starting at 0\n */\nexport function rowNumber<T>(options?: RowNumberOptions) {\n const startAt = options?.startAt ?? 0;\n return (items: T[]) => {\n return items.map((_, i) => i + startAt);\n };\n}\n"],"names":[],"mappings":"mBAQ6B;AAR7B;AASE,QAAM,UAAU,yCAAS,YAAT,YAAoB;AACpC,SAAO,CAAC;AACN,WAAO,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI;AAAA;AAAA;;;;"}
|