@tidyjs/tidy 2.5.1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/dist/es/addRows.js.map +1 -1
  2. package/dist/es/arrange.js +9 -5
  3. package/dist/es/arrange.js.map +1 -1
  4. package/dist/es/complete.js.map +1 -1
  5. package/dist/es/count.js +6 -2
  6. package/dist/es/count.js.map +1 -1
  7. package/dist/es/debug.js +4 -2
  8. package/dist/es/debug.js.map +1 -1
  9. package/dist/es/distinct.js +3 -3
  10. package/dist/es/distinct.js.map +1 -1
  11. package/dist/es/expand.js +18 -13
  12. package/dist/es/expand.js.map +1 -1
  13. package/dist/es/fill.js +10 -3
  14. package/dist/es/fill.js.map +1 -1
  15. package/dist/es/filter.js.map +1 -1
  16. package/dist/es/fullJoin.js +23 -20
  17. package/dist/es/fullJoin.js.map +1 -1
  18. package/dist/es/groupBy.js +56 -28
  19. package/dist/es/groupBy.js.map +1 -1
  20. package/dist/es/helpers/assignGroupKeys.js +4 -4
  21. package/dist/es/helpers/assignGroupKeys.js.map +1 -1
  22. package/dist/es/helpers/groupMap.js +2 -2
  23. package/dist/es/helpers/groupMap.js.map +1 -1
  24. package/dist/es/helpers/groupTraversal.js +5 -4
  25. package/dist/es/helpers/groupTraversal.js.map +1 -1
  26. package/dist/es/helpers/identity.js.map +1 -1
  27. package/dist/es/helpers/isObject.js.map +1 -1
  28. package/dist/es/helpers/keysFromItems.js +1 -2
  29. package/dist/es/helpers/keysFromItems.js.map +1 -1
  30. package/dist/es/helpers/singleOrArray.js.map +1 -1
  31. package/dist/es/helpers/summation.js +11 -3
  32. package/dist/es/helpers/summation.js.map +1 -1
  33. package/dist/es/innerJoin.js +37 -12
  34. package/dist/es/innerJoin.js.map +1 -1
  35. package/dist/es/item/rate.js +2 -3
  36. package/dist/es/item/rate.js.map +1 -1
  37. package/dist/es/leftJoin.js +13 -8
  38. package/dist/es/leftJoin.js.map +1 -1
  39. package/dist/es/map.js.map +1 -1
  40. package/dist/es/math/math.js.map +1 -1
  41. package/dist/es/mutate.js +1 -1
  42. package/dist/es/mutate.js.map +1 -1
  43. package/dist/es/mutateWithSummary.js +1 -1
  44. package/dist/es/mutateWithSummary.js.map +1 -1
  45. package/dist/es/pivotLonger.js +31 -7
  46. package/dist/es/pivotLonger.js.map +1 -1
  47. package/dist/es/pivotWider.js +24 -19
  48. package/dist/es/pivotWider.js.map +1 -1
  49. package/dist/es/rename.js.map +1 -1
  50. package/dist/es/replaceNully.js +1 -1
  51. package/dist/es/replaceNully.js.map +1 -1
  52. package/dist/es/select.js +3 -3
  53. package/dist/es/select.js.map +1 -1
  54. package/dist/es/selectors/contains.js.map +1 -1
  55. package/dist/es/selectors/endsWith.js.map +1 -1
  56. package/dist/es/selectors/everything.js.map +1 -1
  57. package/dist/es/selectors/matches.js.map +1 -1
  58. package/dist/es/selectors/negate.js +2 -2
  59. package/dist/es/selectors/negate.js.map +1 -1
  60. package/dist/es/selectors/numRange.js.map +1 -1
  61. package/dist/es/selectors/startsWith.js.map +1 -1
  62. package/dist/es/sequences/fullSeq.js +5 -1
  63. package/dist/es/sequences/fullSeq.js.map +1 -1
  64. package/dist/es/slice.js +2 -3
  65. package/dist/es/slice.js.map +1 -1
  66. package/dist/es/summarize.js +6 -4
  67. package/dist/es/summarize.js.map +1 -1
  68. package/dist/es/summary/deviation.js.map +1 -1
  69. package/dist/es/summary/first.js.map +1 -1
  70. package/dist/es/summary/last.js.map +1 -1
  71. package/dist/es/summary/max.js.map +1 -1
  72. package/dist/es/summary/mean.js.map +1 -1
  73. package/dist/es/summary/meanRate.js.map +1 -1
  74. package/dist/es/summary/median.js.map +1 -1
  75. package/dist/es/summary/min.js.map +1 -1
  76. package/dist/es/summary/n.js.map +1 -1
  77. package/dist/es/summary/nDistinct.js +2 -2
  78. package/dist/es/summary/nDistinct.js.map +1 -1
  79. package/dist/es/summary/sum.js.map +1 -1
  80. package/dist/es/summary/variance.js.map +1 -1
  81. package/dist/es/tally.js +4 -2
  82. package/dist/es/tally.js.map +1 -1
  83. package/dist/es/tidy.js.map +1 -1
  84. package/dist/es/total.js.map +1 -1
  85. package/dist/es/transmute.js.map +1 -1
  86. package/dist/es/vector/cumsum.js.map +1 -1
  87. package/dist/es/vector/lag.js +1 -1
  88. package/dist/es/vector/lag.js.map +1 -1
  89. package/dist/es/vector/lead.js +1 -1
  90. package/dist/es/vector/lead.js.map +1 -1
  91. package/dist/es/vector/roll.js +1 -1
  92. package/dist/es/vector/roll.js.map +1 -1
  93. package/dist/es/vector/rowNumber.js.map +1 -1
  94. package/dist/es/when.js +1 -2
  95. package/dist/es/when.js.map +1 -1
  96. package/dist/lib/addRows.js +0 -2
  97. package/dist/lib/addRows.js.map +1 -1
  98. package/dist/lib/arrange.js +9 -7
  99. package/dist/lib/arrange.js.map +1 -1
  100. package/dist/lib/complete.js +0 -2
  101. package/dist/lib/complete.js.map +1 -1
  102. package/dist/lib/count.js +6 -4
  103. package/dist/lib/count.js.map +1 -1
  104. package/dist/lib/debug.js +4 -4
  105. package/dist/lib/debug.js.map +1 -1
  106. package/dist/lib/distinct.js +3 -5
  107. package/dist/lib/distinct.js.map +1 -1
  108. package/dist/lib/expand.js +18 -15
  109. package/dist/lib/expand.js.map +1 -1
  110. package/dist/lib/fill.js +10 -5
  111. package/dist/lib/fill.js.map +1 -1
  112. package/dist/lib/filter.js +0 -2
  113. package/dist/lib/filter.js.map +1 -1
  114. package/dist/lib/fullJoin.js +22 -21
  115. package/dist/lib/fullJoin.js.map +1 -1
  116. package/dist/lib/groupBy.js +56 -30
  117. package/dist/lib/groupBy.js.map +1 -1
  118. package/dist/lib/helpers/assignGroupKeys.js +4 -6
  119. package/dist/lib/helpers/assignGroupKeys.js.map +1 -1
  120. package/dist/lib/helpers/groupMap.js +2 -4
  121. package/dist/lib/helpers/groupMap.js.map +1 -1
  122. package/dist/lib/helpers/groupTraversal.js +5 -6
  123. package/dist/lib/helpers/groupTraversal.js.map +1 -1
  124. package/dist/lib/helpers/identity.js +0 -2
  125. package/dist/lib/helpers/identity.js.map +1 -1
  126. package/dist/lib/helpers/isObject.js +0 -2
  127. package/dist/lib/helpers/isObject.js.map +1 -1
  128. package/dist/lib/helpers/keysFromItems.js +1 -4
  129. package/dist/lib/helpers/keysFromItems.js.map +1 -1
  130. package/dist/lib/helpers/singleOrArray.js +0 -2
  131. package/dist/lib/helpers/singleOrArray.js.map +1 -1
  132. package/dist/lib/helpers/summation.js +10 -4
  133. package/dist/lib/helpers/summation.js.map +1 -1
  134. package/dist/lib/index.js +0 -2
  135. package/dist/lib/index.js.map +1 -1
  136. package/dist/lib/innerJoin.js +38 -14
  137. package/dist/lib/innerJoin.js.map +1 -1
  138. package/dist/lib/item/rate.js +2 -5
  139. package/dist/lib/item/rate.js.map +1 -1
  140. package/dist/lib/leftJoin.js +12 -9
  141. package/dist/lib/leftJoin.js.map +1 -1
  142. package/dist/lib/map.js +0 -2
  143. package/dist/lib/map.js.map +1 -1
  144. package/dist/lib/math/math.js +0 -2
  145. package/dist/lib/math/math.js.map +1 -1
  146. package/dist/lib/mutate.js +1 -3
  147. package/dist/lib/mutate.js.map +1 -1
  148. package/dist/lib/mutateWithSummary.js +1 -3
  149. package/dist/lib/mutateWithSummary.js.map +1 -1
  150. package/dist/lib/pivotLonger.js +31 -9
  151. package/dist/lib/pivotLonger.js.map +1 -1
  152. package/dist/lib/pivotWider.js +24 -21
  153. package/dist/lib/pivotWider.js.map +1 -1
  154. package/dist/lib/rename.js +0 -2
  155. package/dist/lib/rename.js.map +1 -1
  156. package/dist/lib/replaceNully.js +1 -3
  157. package/dist/lib/replaceNully.js.map +1 -1
  158. package/dist/lib/select.js +3 -5
  159. package/dist/lib/select.js.map +1 -1
  160. package/dist/lib/selectors/contains.js +0 -2
  161. package/dist/lib/selectors/contains.js.map +1 -1
  162. package/dist/lib/selectors/endsWith.js +0 -2
  163. package/dist/lib/selectors/endsWith.js.map +1 -1
  164. package/dist/lib/selectors/everything.js +0 -2
  165. package/dist/lib/selectors/everything.js.map +1 -1
  166. package/dist/lib/selectors/matches.js +0 -2
  167. package/dist/lib/selectors/matches.js.map +1 -1
  168. package/dist/lib/selectors/negate.js +2 -4
  169. package/dist/lib/selectors/negate.js.map +1 -1
  170. package/dist/lib/selectors/numRange.js +0 -2
  171. package/dist/lib/selectors/numRange.js.map +1 -1
  172. package/dist/lib/selectors/startsWith.js +0 -2
  173. package/dist/lib/selectors/startsWith.js.map +1 -1
  174. package/dist/lib/sequences/fullSeq.js +5 -3
  175. package/dist/lib/sequences/fullSeq.js.map +1 -1
  176. package/dist/lib/slice.js +2 -5
  177. package/dist/lib/slice.js.map +1 -1
  178. package/dist/lib/summarize.js +6 -6
  179. package/dist/lib/summarize.js.map +1 -1
  180. package/dist/lib/summary/deviation.js +0 -2
  181. package/dist/lib/summary/deviation.js.map +1 -1
  182. package/dist/lib/summary/first.js +0 -2
  183. package/dist/lib/summary/first.js.map +1 -1
  184. package/dist/lib/summary/last.js +0 -2
  185. package/dist/lib/summary/last.js.map +1 -1
  186. package/dist/lib/summary/max.js +0 -2
  187. package/dist/lib/summary/max.js.map +1 -1
  188. package/dist/lib/summary/mean.js +0 -2
  189. package/dist/lib/summary/mean.js.map +1 -1
  190. package/dist/lib/summary/meanRate.js +0 -2
  191. package/dist/lib/summary/meanRate.js.map +1 -1
  192. package/dist/lib/summary/median.js +0 -2
  193. package/dist/lib/summary/median.js.map +1 -1
  194. package/dist/lib/summary/min.js +0 -2
  195. package/dist/lib/summary/min.js.map +1 -1
  196. package/dist/lib/summary/n.js +0 -2
  197. package/dist/lib/summary/n.js.map +1 -1
  198. package/dist/lib/summary/nDistinct.js +2 -4
  199. package/dist/lib/summary/nDistinct.js.map +1 -1
  200. package/dist/lib/summary/sum.js +0 -2
  201. package/dist/lib/summary/sum.js.map +1 -1
  202. package/dist/lib/summary/variance.js +0 -2
  203. package/dist/lib/summary/variance.js.map +1 -1
  204. package/dist/lib/tally.js +4 -4
  205. package/dist/lib/tally.js.map +1 -1
  206. package/dist/lib/tidy.js +0 -2
  207. package/dist/lib/tidy.js.map +1 -1
  208. package/dist/lib/total.js +0 -2
  209. package/dist/lib/total.js.map +1 -1
  210. package/dist/lib/transmute.js +0 -2
  211. package/dist/lib/transmute.js.map +1 -1
  212. package/dist/lib/vector/cumsum.js +0 -2
  213. package/dist/lib/vector/cumsum.js.map +1 -1
  214. package/dist/lib/vector/lag.js +1 -3
  215. package/dist/lib/vector/lag.js.map +1 -1
  216. package/dist/lib/vector/lead.js +1 -3
  217. package/dist/lib/vector/lead.js.map +1 -1
  218. package/dist/lib/vector/roll.js +1 -3
  219. package/dist/lib/vector/roll.js.map +1 -1
  220. package/dist/lib/vector/rowNumber.js +0 -2
  221. package/dist/lib/vector/rowNumber.js.map +1 -1
  222. package/dist/lib/when.js +1 -4
  223. package/dist/lib/when.js.map +1 -1
  224. package/dist/tidy.d.ts +217 -1775
  225. package/dist/umd/tidy.js +307 -184
  226. package/dist/umd/tidy.js.map +1 -1
  227. package/dist/umd/tidy.min.js +1 -1
  228. package/dist/umd/tidy.min.js.map +1 -1
  229. package/package.json +14 -9
  230. package/LICENSE +0 -21
package/dist/umd/tidy.js CHANGED
@@ -2,7 +2,7 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', 'd3-array'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Tidy = {}, global.d3));
5
- }(this, (function (exports, d3Array) { 'use strict';
5
+ })(this, (function (exports, d3Array) { 'use strict';
6
6
 
7
7
  function tidy(items, ...fns) {
8
8
  if (typeof items === "function") {
@@ -25,8 +25,7 @@
25
25
  function when(predicate, fns) {
26
26
  const _when = (items) => {
27
27
  if (typeof predicate === "function") {
28
- if (!predicate(items))
29
- return items;
28
+ if (!predicate(items)) return items;
30
29
  } else if (!predicate) {
31
30
  return items;
32
31
  }
@@ -49,13 +48,13 @@
49
48
  const _distinct = (items) => {
50
49
  keys = singleOrArray(keys);
51
50
  if (!keys.length) {
52
- const set = new Set();
51
+ const set = /* @__PURE__ */ new Set();
53
52
  for (const item of items) {
54
53
  set.add(item);
55
54
  }
56
55
  return Array.from(set);
57
56
  }
58
- const rootMap = new Map();
57
+ const rootMap = /* @__PURE__ */ new Map();
59
58
  const distinctItems = [];
60
59
  const lastKey = keys[keys.length - 1];
61
60
  for (const item of items) {
@@ -72,7 +71,7 @@
72
71
  break;
73
72
  }
74
73
  if (!map.has(mapItemKey)) {
75
- map.set(mapItemKey, new Map());
74
+ map.set(mapItemKey, /* @__PURE__ */ new Map());
76
75
  }
77
76
  map = map.get(mapItemKey);
78
77
  }
@@ -84,12 +83,16 @@
84
83
 
85
84
  function arrange(comparators) {
86
85
  const _arrange = (items) => {
87
- const comparatorFns = singleOrArray(comparators).map((comp) => typeof comp === "function" ? comp.length === 1 ? asc(comp) : comp : asc(comp));
86
+ const comparatorFns = singleOrArray(comparators).map(
87
+ (comp) => typeof comp === "function" ? (
88
+ // length === 1 means it is an accessor (1 argument). convert to comparator via asc
89
+ comp.length === 1 ? asc(comp) : comp
90
+ ) : asc(comp)
91
+ );
88
92
  return items.slice().sort((a, b) => {
89
93
  for (const comparator of comparatorFns) {
90
94
  const result = comparator(a, b);
91
- if (result)
92
- return result;
95
+ if (result) return result;
93
96
  }
94
97
  return 0;
95
98
  });
@@ -109,9 +112,9 @@
109
112
  };
110
113
  }
111
114
  function fixedOrder(key, order, options) {
112
- let {position = "start"} = options != null ? options : {};
115
+ let { position = "start" } = options != null ? options : {};
113
116
  const positionFactor = position === "end" ? -1 : 1;
114
- const indexMap = new Map();
117
+ const indexMap = /* @__PURE__ */ new Map();
115
118
  for (let i = 0; i < order.length; ++i) {
116
119
  indexMap.set(order[i], i);
117
120
  }
@@ -162,9 +165,10 @@
162
165
  summarized[key] = summarizeSpec[key](items);
163
166
  }
164
167
  if (options.rest && items.length) {
168
+ const keysSet = new Set(keys);
165
169
  const objectKeys = Object.keys(items[0]);
166
170
  for (const objKey of objectKeys) {
167
- if (keys.includes(objKey)) {
171
+ if (keysSet.has(objKey)) {
168
172
  continue;
169
173
  }
170
174
  summarized[objKey] = options.rest(objKey)(items);
@@ -175,8 +179,7 @@
175
179
  return _summarize;
176
180
  }
177
181
  function _summarizeHelper(items, summaryFn, predicateFn, keys) {
178
- if (!items.length)
179
- return [];
182
+ if (!items.length) return [];
180
183
  const summarized = {};
181
184
  let keysArr;
182
185
  if (keys == null) {
@@ -198,7 +201,9 @@
198
201
  continue;
199
202
  }
200
203
  }
201
- summarized[key] = summaryFn(key)(items);
204
+ summarized[key] = summaryFn(key)(
205
+ items
206
+ );
202
207
  }
203
208
  return [summarized];
204
209
  }
@@ -217,7 +222,7 @@
217
222
 
218
223
  function mutate(mutateSpec) {
219
224
  const _mutate = (items) => {
220
- const mutatedItems = items.map((d) => ({...d}));
225
+ const mutatedItems = items.map((d) => ({ ...d }));
221
226
  let i = 0;
222
227
  for (const mutatedItem of mutatedItems) {
223
228
  for (const key in mutateSpec) {
@@ -265,36 +270,37 @@
265
270
  return _totalAt;
266
271
  }
267
272
 
268
- function assignGroupKeys(d, keys) {
269
- if (d == null || typeof d !== "object" || Array.isArray(d))
270
- return d;
271
- const keysObj = Object.fromEntries(keys.filter((key) => typeof key[0] !== "function"));
273
+ function assignGroupKeys(d, keys, filteredKeys) {
274
+ if (d == null || typeof d !== "object" || Array.isArray(d)) return d;
275
+ const validKeys = filteredKeys != null ? filteredKeys : keys.filter((key) => typeof key[0] !== "function" && key[0] != null);
276
+ const keysObj = Object.fromEntries(validKeys);
272
277
  return Object.assign(keysObj, d);
273
278
  }
274
279
 
275
280
  function groupTraversal(grouped, outputGrouped, keys, addSubgroup, addLeaves, level = 0) {
276
281
  for (const [key, value] of grouped.entries()) {
277
- const keysHere = [...keys, key];
282
+ keys.push(key);
278
283
  if (value instanceof Map) {
279
- const subgroup = addSubgroup(outputGrouped, keysHere, level);
280
- groupTraversal(value, subgroup, keysHere, addSubgroup, addLeaves, level + 1);
284
+ const subgroup = addSubgroup(outputGrouped, keys, level);
285
+ groupTraversal(value, subgroup, keys, addSubgroup, addLeaves, level + 1);
281
286
  } else {
282
- addLeaves(outputGrouped, keysHere, value, level);
287
+ addLeaves(outputGrouped, keys, value, level);
283
288
  }
289
+ keys.pop();
284
290
  }
285
291
  return outputGrouped;
286
292
  }
287
293
 
288
294
  function groupMap(grouped, groupFn, keyFn = (keys) => keys[keys.length - 1]) {
289
295
  function addSubgroup(parentGrouped, keys) {
290
- const subgroup = new Map();
296
+ const subgroup = /* @__PURE__ */ new Map();
291
297
  parentGrouped.set(keyFn(keys), subgroup);
292
298
  return subgroup;
293
299
  }
294
300
  function addLeaves(parentGrouped, keys, values) {
295
301
  parentGrouped.set(keyFn(keys), groupFn(values, keys));
296
302
  }
297
- const outputGrouped = new Map();
303
+ const outputGrouped = /* @__PURE__ */ new Map();
298
304
  groupTraversal(grouped, outputGrouped, [], addSubgroup, addLeaves);
299
305
  return outputGrouped;
300
306
  }
@@ -312,9 +318,13 @@
312
318
  } else if (arguments.length === 2 && fns != null && !Array.isArray(fns)) {
313
319
  options = fns;
314
320
  }
315
- const _groupBy = (items) => {
321
+ const _groupBy = ((items) => {
316
322
  const grouped = makeGrouped(items, groupKeys);
317
- const results = runFlow(grouped, fns, options == null ? void 0 : options.addGroupKeys);
323
+ const results = runFlow(
324
+ grouped,
325
+ fns,
326
+ options == null ? void 0 : options.addGroupKeys
327
+ );
318
328
  if (options == null ? void 0 : options.export) {
319
329
  switch (options.export) {
320
330
  case "grouped":
@@ -338,29 +348,33 @@
338
348
  }
339
349
  const ungrouped = ungroup(results, options == null ? void 0 : options.addGroupKeys);
340
350
  return ungrouped;
341
- };
351
+ });
342
352
  return _groupBy;
343
353
  }
344
- groupBy.grouped = (options) => ({...options, export: "grouped"});
345
- groupBy.entries = (options) => ({...options, export: "entries"});
346
- groupBy.entriesObject = (options) => ({...options, export: "entries-object"});
347
- groupBy.object = (options) => ({...options, export: "object"});
348
- groupBy.map = (options) => ({...options, export: "map"});
349
- groupBy.keys = (options) => ({...options, export: "keys"});
350
- groupBy.values = (options) => ({...options, export: "values"});
351
- groupBy.levels = (options) => ({...options, export: "levels"});
354
+ groupBy.grouped = (options) => ({ ...options, export: "grouped" });
355
+ groupBy.entries = (options) => ({ ...options, export: "entries" });
356
+ groupBy.entriesObject = (options) => ({ ...options, export: "entries-object" });
357
+ groupBy.object = (options) => ({ ...options, export: "object" });
358
+ groupBy.map = (options) => ({ ...options, export: "map" });
359
+ groupBy.keys = (options) => ({ ...options, export: "keys" });
360
+ groupBy.values = (options) => ({ ...options, export: "values" });
361
+ groupBy.levels = (options) => ({ ...options, export: "levels" });
352
362
  function runFlow(items, fns, addGroupKeys) {
353
363
  let result = items;
354
- if (!(fns == null ? void 0 : fns.length))
355
- return result;
364
+ if (!(fns == null ? void 0 : fns.length)) return result;
356
365
  for (const fn of fns) {
357
- if (!fn)
358
- continue;
366
+ if (!fn) continue;
359
367
  result = groupMap(result, (items2, keys) => {
360
- const context = {groupKeys: keys};
368
+ const keysSnapshot = keys.slice();
369
+ const context = { groupKeys: keysSnapshot };
361
370
  let leafItemsMapped = fn(items2, context);
362
371
  if (addGroupKeys !== false) {
363
- leafItemsMapped = leafItemsMapped.map((item) => assignGroupKeys(item, keys));
372
+ const filteredKeys = keysSnapshot.filter(
373
+ (key) => typeof key[0] !== "function" && key[0] != null
374
+ );
375
+ leafItemsMapped = leafItemsMapped.map(
376
+ (item) => assignGroupKeys(item, keysSnapshot, filteredKeys)
377
+ );
364
378
  }
365
379
  return leafItemsMapped;
366
380
  });
@@ -368,9 +382,9 @@
368
382
  return result;
369
383
  }
370
384
  function makeGrouped(items, groupKeys) {
371
- const groupKeyFns = singleOrArray(groupKeys).map((key, i) => {
385
+ const groupKeyFns = singleOrArray(groupKeys).map((key) => {
372
386
  const keyFn = typeof key === "function" ? key : (d) => d[key];
373
- const keyCache = new Map();
387
+ const keyCache = /* @__PURE__ */ new Map();
374
388
  return (d) => {
375
389
  const keyValue = keyFn(d);
376
390
  const keyValueOf = isObject(keyValue) ? keyValue.valueOf() : keyValue;
@@ -390,7 +404,10 @@
390
404
  groupTraversal(grouped, items, [], identity, (root, keys, values) => {
391
405
  let valuesToAdd = values;
392
406
  if (addGroupKeys !== false) {
393
- valuesToAdd = values.map((d) => assignGroupKeys(d, keys));
407
+ const filteredKeys = keys.filter(
408
+ (key) => typeof key[0] !== "function" && key[0] != null
409
+ );
410
+ valuesToAdd = values.map((d) => assignGroupKeys(d, keys, filteredKeys));
394
411
  }
395
412
  root.push(...valuesToAdd);
396
413
  });
@@ -411,23 +428,30 @@
411
428
  compositeKey = (_a = options.compositeKey) != null ? _a : defaultCompositeKey;
412
429
  }
413
430
  const groupFn = (values, keys) => {
414
- return single ? mapLeaf(addGroupKeys === false ? values[0] : assignGroupKeys(values[0], keys)) : mapLeaves(values.map((d) => mapLeaf(addGroupKeys === false ? d : assignGroupKeys(d, keys))));
431
+ return single ? mapLeaf(
432
+ addGroupKeys === false ? values[0] : assignGroupKeys(values[0], keys)
433
+ ) : mapLeaves(
434
+ values.map(
435
+ (d) => mapLeaf(addGroupKeys === false ? d : assignGroupKeys(d, keys))
436
+ )
437
+ );
415
438
  };
416
439
  const keyFn = flat ? (keys) => compositeKey(keys.map((d) => d[1])) : (keys) => keys[keys.length - 1][1];
417
- return {groupFn, keyFn};
440
+ return { groupFn, keyFn };
418
441
  }
419
442
  function exportLevels(grouped, options) {
420
- const {groupFn, keyFn} = processFromGroupsOptions(options);
421
- let {mapEntry = identity} = options;
422
- const {levels = ["entries"]} = options;
443
+ const { groupFn, keyFn } = processFromGroupsOptions(options);
444
+ let { mapEntry = identity } = options;
445
+ const { levels = ["entries"] } = options;
423
446
  const levelSpecs = [];
424
447
  for (const levelOption of levels) {
425
448
  switch (levelOption) {
449
+ // entries / entries-object -----------------------------------------
426
450
  case "entries":
427
451
  case "entries-object":
428
452
  case "entries-obj":
429
453
  case "entriesObject": {
430
- const levelMapEntry = (levelOption === "entries-object" || levelOption === "entries-obj" || levelOption === "entriesObject") && options.mapEntry == null ? ([key, values]) => ({key, values}) : mapEntry;
454
+ const levelMapEntry = (levelOption === "entries-object" || levelOption === "entries-obj" || levelOption === "entriesObject") && options.mapEntry == null ? ([key, values]) => ({ key, values }) : mapEntry;
431
455
  levelSpecs.push({
432
456
  id: "entries",
433
457
  createEmptySubgroup: () => [],
@@ -440,10 +464,11 @@
440
464
  });
441
465
  break;
442
466
  }
467
+ // map -------------------------------------------------------------
443
468
  case "map":
444
469
  levelSpecs.push({
445
470
  id: "map",
446
- createEmptySubgroup: () => new Map(),
471
+ createEmptySubgroup: () => /* @__PURE__ */ new Map(),
447
472
  addSubgroup: (parentGrouped, newSubgroup, key) => {
448
473
  parentGrouped.set(key, newSubgroup);
449
474
  },
@@ -452,6 +477,7 @@
452
477
  }
453
478
  });
454
479
  break;
480
+ // object ----------------------------------------------------------
455
481
  case "object":
456
482
  levelSpecs.push({
457
483
  id: "object",
@@ -464,6 +490,7 @@
464
490
  }
465
491
  });
466
492
  break;
493
+ // keys ------------------------------------------------------------
467
494
  case "keys":
468
495
  levelSpecs.push({
469
496
  id: "keys",
@@ -476,6 +503,7 @@
476
503
  }
477
504
  });
478
505
  break;
506
+ // values ----------------------------------------------------------
479
507
  case "values":
480
508
  levelSpecs.push({
481
509
  id: "values",
@@ -488,6 +516,7 @@
488
516
  }
489
517
  });
490
518
  break;
519
+ // custom ----------------------------------------------------------
491
520
  default: {
492
521
  if (typeof levelOption === "object") {
493
522
  levelSpecs.push(levelOption);
@@ -509,7 +538,12 @@
509
538
  const addLeaf = (parentGrouped, keys, values, level) => {
510
539
  var _a;
511
540
  const levelSpec = (_a = levelSpecs[level]) != null ? _a : levelSpecs[levelSpecs.length - 1];
512
- levelSpec.addLeaf(parentGrouped, keyFn(keys), groupFn(values, keys), level);
541
+ levelSpec.addLeaf(
542
+ parentGrouped,
543
+ keyFn(keys),
544
+ groupFn(values, keys),
545
+ level
546
+ );
513
547
  };
514
548
  const initialOutputObject = levelSpecs[0].createEmptySubgroup();
515
549
  return groupTraversal(grouped, initialOutputObject, [], addSubgroup, addLeaf);
@@ -535,8 +569,10 @@
535
569
 
536
570
  function tally(options) {
537
571
  const _tally = (items) => {
538
- const {name = "n", wt} = options != null ? options : {};
539
- const summarized = summarize({[name]: wt == null ? n() : sum(wt)})(items);
572
+ const { name = "n", wt } = options != null ? options : {};
573
+ const summarized = summarize({ [name]: wt == null ? n() : sum(wt) })(
574
+ items
575
+ );
540
576
  return summarized;
541
577
  };
542
578
  return _tally;
@@ -545,8 +581,12 @@
545
581
  function count(groupKeys, options) {
546
582
  const _count = (items) => {
547
583
  options = options != null ? options : {};
548
- const {name = "n", sort} = options;
549
- const results = tidy(items, groupBy(groupKeys, [tally(options)]), sort ? arrange(desc(name)) : identity);
584
+ const { name = "n", sort } = options;
585
+ const results = tidy(
586
+ items,
587
+ groupBy(groupKeys, [tally(options)]),
588
+ sort ? arrange(desc(name)) : identity
589
+ );
550
590
  return results;
551
591
  };
552
592
  return _count;
@@ -584,10 +624,9 @@
584
624
  }
585
625
  function sliceSample(n, options) {
586
626
  options = options != null ? options : {};
587
- const {replace} = options;
627
+ const { replace } = options;
588
628
  const _sliceSample = (items) => {
589
- if (!items.length)
590
- return items.slice();
629
+ if (!items.length) return items.slice();
591
630
  if (replace) {
592
631
  const sliced = [];
593
632
  for (let i = 0; i < n; ++i) {
@@ -601,8 +640,7 @@
601
640
  }
602
641
 
603
642
  function autodetectByMap(itemsA, itemsB) {
604
- if (itemsA.length === 0 || itemsB.length === 0)
605
- return {};
643
+ if (itemsA.length === 0 || itemsB.length === 0) return {};
606
644
  const keysA = Object.keys(itemsA[0]);
607
645
  const keysB = Object.keys(itemsB[0]);
608
646
  const byMap = {};
@@ -623,23 +661,49 @@
623
661
  } else if (typeof by === "object") {
624
662
  return by;
625
663
  }
626
- return {[by]: by};
627
- }
628
- function isMatch(d, j, byMap) {
629
- for (const jKey in byMap) {
630
- const dKey = byMap[jKey];
631
- if (d[dKey] !== j[jKey]) {
632
- return false;
664
+ return { [by]: by };
665
+ }
666
+ const KEY_DELIMITER = "\0";
667
+ const NULL_SENTINEL = "N";
668
+ const UNDEF_SENTINEL = "U";
669
+ function serializeValue(v) {
670
+ if (v === null) return NULL_SENTINEL;
671
+ if (v === void 0) return UNDEF_SENTINEL;
672
+ return String(v);
673
+ }
674
+ function computeKey(row, keys) {
675
+ if (keys.length === 1) return serializeValue(row[keys[0]]);
676
+ let key = "";
677
+ for (let i = 0; i < keys.length; i++) {
678
+ if (i > 0) key += KEY_DELIMITER;
679
+ key += serializeValue(row[keys[i]]);
680
+ }
681
+ return key;
682
+ }
683
+ function buildJoinIndex(itemsToJoin, joinKeys) {
684
+ const index = /* @__PURE__ */ new Map();
685
+ for (const j of itemsToJoin) {
686
+ const key = computeKey(j, joinKeys);
687
+ let bucket = index.get(key);
688
+ if (bucket === void 0) {
689
+ bucket = [];
690
+ index.set(key, bucket);
633
691
  }
692
+ bucket.push(j);
634
693
  }
635
- return true;
694
+ return index;
636
695
  }
637
696
  function innerJoin(itemsToJoin, options) {
638
697
  const _innerJoin = (items) => {
639
698
  const byMap = (options == null ? void 0 : options.by) == null ? autodetectByMap(items, itemsToJoin) : makeByMap(options.by);
699
+ const joinKeys = Object.keys(byMap);
700
+ const itemKeys = joinKeys.map((jKey) => byMap[jKey]);
701
+ const index = buildJoinIndex(itemsToJoin, joinKeys);
640
702
  const joined = items.flatMap((d) => {
641
- const matches = itemsToJoin.filter((j) => isMatch(d, j, byMap));
642
- return matches.map((j) => ({...d, ...j}));
703
+ const key = computeKey(d, itemKeys);
704
+ const matches = index.get(key);
705
+ if (matches === void 0) return [];
706
+ return matches.map((j) => ({ ...d, ...j }));
643
707
  });
644
708
  return joined;
645
709
  };
@@ -648,17 +712,22 @@
648
712
 
649
713
  function leftJoin(itemsToJoin, options) {
650
714
  const _leftJoin = (items) => {
651
- if (!itemsToJoin.length)
652
- return items;
715
+ if (!itemsToJoin.length) return items;
653
716
  const byMap = (options == null ? void 0 : options.by) == null ? autodetectByMap(items, itemsToJoin) : makeByMap(options.by);
717
+ const joinKeys = Object.keys(byMap);
718
+ const itemKeys = joinKeys.map((jKey) => byMap[jKey]);
719
+ const index = buildJoinIndex(itemsToJoin, joinKeys);
654
720
  const joinObjectKeys = Object.keys(itemsToJoin[0]);
655
721
  const joined = items.flatMap((d) => {
656
- const matches = itemsToJoin.filter((j) => isMatch(d, j, byMap));
657
- if (matches.length) {
658
- return matches.map((j) => ({...d, ...j}));
722
+ const key = computeKey(d, itemKeys);
723
+ const matches = index.get(key);
724
+ if (matches !== void 0) {
725
+ return matches.map((j) => ({ ...d, ...j }));
659
726
  }
660
- const undefinedFill = Object.fromEntries(joinObjectKeys.filter((key) => d[key] == null).map((key) => [key, void 0]));
661
- return {...d, ...undefinedFill};
727
+ const undefinedFill = Object.fromEntries(
728
+ joinObjectKeys.filter((key2) => d[key2] == null).map((key2) => [key2, void 0])
729
+ );
730
+ return { ...d, ...undefinedFill };
662
731
  });
663
732
  return joined;
664
733
  };
@@ -667,32 +736,35 @@
667
736
 
668
737
  function fullJoin(itemsToJoin, options) {
669
738
  const _fullJoin = (items) => {
670
- if (!itemsToJoin.length)
671
- return items;
672
- if (!items.length)
673
- return itemsToJoin;
739
+ if (!itemsToJoin.length) return items;
740
+ if (!items.length) return itemsToJoin;
674
741
  const byMap = (options == null ? void 0 : options.by) == null ? autodetectByMap(items, itemsToJoin) : makeByMap(options.by);
675
- const matchMap = new Map();
742
+ const joinKeys = Object.keys(byMap);
743
+ const itemKeys = joinKeys.map((jKey) => byMap[jKey]);
744
+ const index = buildJoinIndex(itemsToJoin, joinKeys);
745
+ const matchedItems = /* @__PURE__ */ new Set();
676
746
  const joinObjectKeys = Object.keys(itemsToJoin[0]);
677
747
  const joined = items.flatMap((d) => {
678
- const matches = itemsToJoin.filter((j) => {
679
- const matched = isMatch(d, j, byMap);
680
- if (matched) {
681
- matchMap.set(j, true);
748
+ const key = computeKey(d, itemKeys);
749
+ const matches = index.get(key);
750
+ if (matches !== void 0) {
751
+ for (const j of matches) {
752
+ matchedItems.add(j);
682
753
  }
683
- return matched;
684
- });
685
- if (matches.length) {
686
- return matches.map((j) => ({...d, ...j}));
754
+ return matches.map((j) => ({ ...d, ...j }));
687
755
  }
688
- const undefinedFill = Object.fromEntries(joinObjectKeys.filter((key) => d[key] == null).map((key) => [key, void 0]));
689
- return {...d, ...undefinedFill};
756
+ const undefinedFill = Object.fromEntries(
757
+ joinObjectKeys.filter((key2) => d[key2] == null).map((key2) => [key2, void 0])
758
+ );
759
+ return { ...d, ...undefinedFill };
690
760
  });
691
- if (matchMap.size < itemsToJoin.length) {
692
- const leftEmptyObject = Object.fromEntries(Object.keys(items[0]).map((key) => [key, void 0]));
761
+ if (matchedItems.size < itemsToJoin.length) {
762
+ const leftEmptyObject = Object.fromEntries(
763
+ Object.keys(items[0]).map((key) => [key, void 0])
764
+ );
693
765
  for (const item of itemsToJoin) {
694
- if (!matchMap.has(item)) {
695
- joined.push({...leftEmptyObject, ...item});
766
+ if (!matchedItems.has(item)) {
767
+ joined.push({ ...leftEmptyObject, ...item });
696
768
  }
697
769
  }
698
770
  }
@@ -703,7 +775,7 @@
703
775
 
704
776
  function mutateWithSummary(mutateSpec) {
705
777
  const _mutate = (items) => {
706
- const mutatedItems = items.map((d) => ({...d}));
778
+ const mutatedItems = items.map((d) => ({ ...d }));
707
779
  for (const key in mutateSpec) {
708
780
  const mutateSpecValue = mutateSpec[key];
709
781
  const mutatedResult = typeof mutateSpecValue === "function" ? mutateSpecValue(mutatedItems) : mutateSpecValue;
@@ -719,8 +791,7 @@
719
791
  }
720
792
 
721
793
  function keysFromItems(items) {
722
- if (items.length < 1)
723
- return [];
794
+ if (items.length < 1) return [];
724
795
  const keys = Object.keys(items[0]);
725
796
  return keys;
726
797
  }
@@ -756,16 +827,16 @@
756
827
  negationMap[key] = false;
757
828
  continue;
758
829
  }
759
- keysWithoutNegations.unshift(key);
830
+ keysWithoutNegations.push(key);
760
831
  }
832
+ keysWithoutNegations.reverse();
761
833
  processedSelectKeys = Array.from(new Set(keysWithoutNegations));
762
834
  return processedSelectKeys;
763
835
  }
764
836
  function select(selectKeys) {
765
837
  const _select = (items) => {
766
838
  let processedSelectKeys = processSelectors(items, selectKeys);
767
- if (!processedSelectKeys.length)
768
- return items;
839
+ if (!processedSelectKeys.length) return items;
769
840
  return items.map((d) => {
770
841
  const mapped = {};
771
842
  for (const key of processedSelectKeys) {
@@ -808,9 +879,10 @@
808
879
  const namesFromKeys = Array.isArray(namesFrom) ? namesFrom : [namesFrom];
809
880
  const valuesFromKeys = Array.isArray(valuesFrom) ? valuesFrom : [valuesFrom];
810
881
  const wider = [];
811
- if (!items.length)
812
- return wider;
813
- const idColumns = Object.keys(items[0]).filter((key) => !namesFromKeys.includes(key) && !valuesFromKeys.includes(key));
882
+ if (!items.length) return wider;
883
+ const idColumns = Object.keys(items[0]).filter(
884
+ (key) => !namesFromKeys.includes(key) && !valuesFromKeys.includes(key)
885
+ );
814
886
  const nameValuesMap = {};
815
887
  for (const item of items) {
816
888
  for (const nameKey of namesFromKeys) {
@@ -825,20 +897,19 @@
825
897
  nameValuesLists.push(Object.keys(nameValuesMap[nameKey]));
826
898
  }
827
899
  const baseWideObj = {};
828
- const combos = makeCombinations(namesSep, nameValuesLists);
900
+ const combos = makeCombinations$1(namesSep, nameValuesLists);
829
901
  for (const nameKey of combos) {
830
902
  if (valuesFromKeys.length === 1) {
831
903
  baseWideObj[nameKey] = valuesFillMap != null ? valuesFillMap[valuesFromKeys[0]] : valuesFill;
832
904
  continue;
833
905
  }
834
906
  for (const valueKey of valuesFromKeys) {
835
- baseWideObj[`${valueKey}${namesSep}${nameKey}`] = valuesFillMap != null ? valuesFillMap[valueKey] : valuesFill;
907
+ baseWideObj[`${String(valueKey)}${namesSep}${nameKey}`] = valuesFillMap != null ? valuesFillMap[valueKey] : valuesFill;
836
908
  }
837
909
  }
838
910
  function widenItems(items2) {
839
- if (!items2.length)
840
- return [];
841
- const wide = {...baseWideObj};
911
+ if (!items2.length) return [];
912
+ const wide = { ...baseWideObj };
842
913
  for (const idKey of idColumns) {
843
914
  wide[idKey] = items2[0][idKey];
844
915
  }
@@ -849,7 +920,7 @@
849
920
  continue;
850
921
  }
851
922
  for (const valueKey of valuesFromKeys) {
852
- wide[`${valueKey}${namesSep}${nameKey}`] = item[valueKey];
923
+ wide[`${String(valueKey)}${namesSep}${nameKey}`] = item[valueKey];
853
924
  }
854
925
  }
855
926
  return [wide];
@@ -862,27 +933,32 @@
862
933
  };
863
934
  return _pivotWider;
864
935
  }
865
- function makeCombinations(separator = "_", arrays) {
866
- function combine(accum, prefix, remainingArrays) {
867
- if (!remainingArrays.length && prefix != null) {
868
- accum.push(prefix);
869
- return;
870
- }
871
- const array = remainingArrays[0];
872
- const newRemainingArrays = remainingArrays.slice(1);
873
- for (const item of array) {
874
- combine(accum, prefix == null ? item : `${prefix}${separator}${item}`, newRemainingArrays);
936
+ const PIVOT_WARN_THRESHOLD = 1e5;
937
+ function makeCombinations$1(separator = "_", arrays) {
938
+ if (!arrays.length) return [];
939
+ const totalSize = arrays.reduce((acc, v) => acc * v.length, 1);
940
+ if (totalSize > PIVOT_WARN_THRESHOLD) {
941
+ console.warn(
942
+ `tidy pivotWider: generating ${totalSize.toLocaleString()} column combinations. This may be slow or use excessive memory.`
943
+ );
944
+ }
945
+ let result = [null];
946
+ for (const array of arrays) {
947
+ const next = [];
948
+ for (const prefix of result) {
949
+ for (const item of array) {
950
+ next.push(prefix == null ? item : `${prefix}${separator}${item}`);
951
+ }
875
952
  }
953
+ result = next;
876
954
  }
877
- const result = [];
878
- combine(result, null, arrays);
879
955
  return result;
880
956
  }
881
957
 
882
958
  function pivotLonger(options) {
883
959
  const _pivotLonger = (items) => {
884
960
  var _a;
885
- const {namesTo, valuesTo, namesSep = "_"} = options;
961
+ const { namesTo, valuesTo, namesSep = "_" } = options;
886
962
  const cols = (_a = options.cols) != null ? _a : [];
887
963
  const colsKeys = processSelectors(items, cols);
888
964
  const namesToKeys = Array.isArray(namesTo) ? namesTo : [namesTo];
@@ -890,18 +966,42 @@
890
966
  const hasMultipleNamesTo = namesToKeys.length > 1;
891
967
  const hasMultipleValuesTo = valuesToKeys.length > 1;
892
968
  const longer = [];
969
+ if (!items.length) return longer;
970
+ const colsKeysSet = new Set(colsKeys);
971
+ const remainingKeys = Object.keys(items[0]).filter(
972
+ (key) => !colsKeysSet.has(key)
973
+ );
974
+ const nameValueKeysWithoutValuePrefix = hasMultipleValuesTo ? Array.from(
975
+ new Set(
976
+ colsKeys.map(
977
+ (key) => key.substring(key.indexOf(namesSep) + 1)
978
+ )
979
+ )
980
+ ) : colsKeys;
981
+ const nameValuePartsMap = hasMultipleNamesTo ? new Map(
982
+ nameValueKeysWithoutValuePrefix.map((nv) => [
983
+ nv,
984
+ nv.split(namesSep)
985
+ ])
986
+ ) : null;
987
+ const itemKeysMap = hasMultipleValuesTo ? new Map(
988
+ nameValueKeysWithoutValuePrefix.map((nv) => [
989
+ nv,
990
+ valuesToKeys.map((vk) => `${String(vk)}${namesSep}${String(nv)}`)
991
+ ])
992
+ ) : null;
893
993
  for (const item of items) {
894
- const remainingKeys = Object.keys(item).filter((key) => !colsKeys.includes(key));
895
994
  const baseObj = {};
896
995
  for (const key of remainingKeys) {
897
996
  baseObj[key] = item[key];
898
997
  }
899
- const nameValueKeysWithoutValuePrefix = hasMultipleValuesTo ? Array.from(new Set(colsKeys.map((key) => key.substring(key.indexOf(namesSep) + 1)))) : colsKeys;
900
998
  for (const nameValue of nameValueKeysWithoutValuePrefix) {
901
- const entryObj = {...baseObj};
902
- for (const valueKey of valuesToKeys) {
903
- const itemKey = hasMultipleValuesTo ? `${valueKey}${namesSep}${nameValue}` : nameValue;
904
- const nameValueParts = hasMultipleNamesTo ? nameValue.split(namesSep) : [nameValue];
999
+ const entryObj = { ...baseObj };
1000
+ const nameValueParts = nameValuePartsMap ? nameValuePartsMap.get(nameValue) : [nameValue];
1001
+ const itemKeys = itemKeysMap ? itemKeysMap.get(nameValue) : null;
1002
+ for (let vi = 0; vi < valuesToKeys.length; vi++) {
1003
+ const valueKey = valuesToKeys[vi];
1004
+ const itemKey = itemKeys ? itemKeys[vi] : nameValue;
905
1005
  let i = 0;
906
1006
  for (const nameKey of namesToKeys) {
907
1007
  const nameValuePart = nameValueParts[i++];
@@ -931,26 +1031,31 @@
931
1031
  } else {
932
1032
  values = Array.from(new Set(items.map((d) => d[key])));
933
1033
  }
934
- vectors.push(values.map((value) => ({[key]: value})));
1034
+ vectors.push(values.map((value) => ({ [key]: value })));
935
1035
  }
936
- return makeCombinations$1(vectors);
1036
+ return makeCombinations(vectors);
937
1037
  };
938
1038
  return _expand;
939
1039
  }
940
- function makeCombinations$1(vectors) {
941
- function combine(accum, baseObj, remainingVectors) {
942
- if (!remainingVectors.length && baseObj != null) {
943
- accum.push(baseObj);
944
- return;
945
- }
946
- const vector = remainingVectors[0];
947
- const newRemainingArrays = remainingVectors.slice(1);
948
- for (const item of vector) {
949
- combine(accum, {...baseObj, ...item}, newRemainingArrays);
1040
+ const EXPAND_WARN_THRESHOLD = 1e5;
1041
+ function makeCombinations(vectors) {
1042
+ if (!vectors.length) return [];
1043
+ const totalSize = vectors.reduce((acc, v) => acc * v.length, 1);
1044
+ if (totalSize > EXPAND_WARN_THRESHOLD) {
1045
+ console.warn(
1046
+ `tidy expand: generating ${totalSize.toLocaleString()} combinations. This may be slow or use excessive memory.`
1047
+ );
1048
+ }
1049
+ let result = [null];
1050
+ for (const vector of vectors) {
1051
+ const next = [];
1052
+ for (const baseObj of result) {
1053
+ for (const item of vector) {
1054
+ next.push(baseObj == null ? item : { ...baseObj, ...item });
1055
+ }
950
1056
  }
1057
+ result = next;
951
1058
  }
952
- const result = [];
953
- combine(result, null, vectors);
954
1059
  return result;
955
1060
  }
956
1061
  function makeKeyMap(keys) {
@@ -963,7 +1068,7 @@
963
1068
  } else if (typeof keys === "object") {
964
1069
  return keys;
965
1070
  }
966
- return {[keys]: keys};
1071
+ return { [keys]: keys };
967
1072
  }
968
1073
 
969
1074
  function vectorSeq(values, period = 1) {
@@ -1020,7 +1125,11 @@
1020
1125
  granularity = granularity != null ? granularity : "day";
1021
1126
  period = period != null ? period : 1;
1022
1127
  const keyFn = typeof key === "function" ? key : (d) => d[key];
1023
- return vectorSeqDate(items.map((d) => new Date(keyFn(d))), granularity, period).map((date) => date.toISOString());
1128
+ return vectorSeqDate(
1129
+ items.map((d) => new Date(keyFn(d))),
1130
+ granularity,
1131
+ period
1132
+ ).map((date) => date.toISOString());
1024
1133
  };
1025
1134
  }
1026
1135
 
@@ -1028,7 +1137,7 @@
1028
1137
  const _replaceNully = (items) => {
1029
1138
  const replacedItems = [];
1030
1139
  for (const d of items) {
1031
- const obj = {...d};
1140
+ const obj = { ...d };
1032
1141
  for (const key in replaceSpec) {
1033
1142
  if (obj[key] == null) {
1034
1143
  obj[key] = replaceSpec[key];
@@ -1055,11 +1164,18 @@
1055
1164
  const keysArray = singleOrArray(keys);
1056
1165
  const replaceMap = {};
1057
1166
  return items.map((d) => {
1058
- const obj = {...d};
1167
+ let needsCopy = false;
1059
1168
  for (const key of keysArray) {
1060
- if (obj[key] != null) {
1061
- replaceMap[key] = obj[key];
1169
+ if (d[key] != null) {
1170
+ replaceMap[key] = d[key];
1062
1171
  } else if (replaceMap[key] != null) {
1172
+ needsCopy = true;
1173
+ }
1174
+ }
1175
+ if (!needsCopy) return d;
1176
+ const obj = { ...d };
1177
+ for (const key of keysArray) {
1178
+ if (obj[key] == null && replaceMap[key] != null) {
1063
1179
  obj[key] = replaceMap[key];
1064
1180
  }
1065
1181
  }
@@ -1081,19 +1197,21 @@
1081
1197
  }
1082
1198
  }
1083
1199
  options = options != null ? options : {};
1084
- const {limit = 10, output = "table"} = options;
1200
+ const { limit = 10, output = "table" } = options;
1085
1201
  const dashString = "--------------------------------------------------------------------------------";
1086
1202
  let numDashes = dashString.length;
1087
1203
  const prefixedLabel = prefix + "]" + (label == null ? "" : " " + label);
1088
1204
  numDashes = Math.max(0, numDashes - (prefixedLabel.length + 2));
1089
1205
  console.log(`${prefixedLabel} ${dashString.substring(0, numDashes)}`);
1090
- console[output](limit == null || limit >= items.length ? items : items.slice(0, limit));
1206
+ console[output](
1207
+ limit == null || limit >= items.length ? items : items.slice(0, limit)
1208
+ );
1091
1209
  return items;
1092
1210
  };
1093
1211
  return _debug;
1094
1212
  }
1095
1213
 
1096
- function rate(numerator, denominator, allowDivideByZero) {
1214
+ function rate$1(numerator, denominator, allowDivideByZero) {
1097
1215
  return numerator == null || denominator == null ? void 0 : denominator === 0 && numerator === 0 ? 0 : !allowDivideByZero && denominator === 0 ? void 0 : numerator / denominator;
1098
1216
  }
1099
1217
  function subtract(a, b, nullyZero) {
@@ -1105,41 +1223,48 @@
1105
1223
 
1106
1224
  var math = /*#__PURE__*/Object.freeze({
1107
1225
  __proto__: null,
1108
- rate: rate,
1109
- subtract: subtract,
1110
- add: add
1226
+ add: add,
1227
+ rate: rate$1,
1228
+ subtract: subtract
1111
1229
  });
1112
1230
 
1113
- function rate$1(numerator, denominator, options) {
1231
+ function rate(numerator, denominator, options) {
1114
1232
  const numeratorFn = typeof numerator === "function" ? numerator : (d) => d[numerator];
1115
1233
  const denominatorFn = typeof denominator === "function" ? denominator : (d) => d[denominator];
1116
- const {predicate, allowDivideByZero} = options != null ? options : {};
1234
+ const { predicate, allowDivideByZero } = options != null ? options : {};
1117
1235
  return predicate == null ? (d, index, array) => {
1118
1236
  const denom = denominatorFn(d, index, array);
1119
1237
  const numer = numeratorFn(d, index, array);
1120
- return rate(numer, denom, allowDivideByZero);
1238
+ return rate$1(numer, denom, allowDivideByZero);
1121
1239
  } : (d, index, array) => {
1122
- if (!predicate(d, index, array))
1123
- return void 0;
1240
+ if (!predicate(d, index, array)) return void 0;
1124
1241
  const denom = denominatorFn(d, index, array);
1125
1242
  const numer = numeratorFn(d, index, array);
1126
- return rate(numer, denom, allowDivideByZero);
1243
+ return rate$1(numer, denom, allowDivideByZero);
1127
1244
  };
1128
1245
  }
1129
1246
 
1130
1247
  function fcumsum(items, accessor) {
1131
1248
  let sum = new d3Array.Adder(), i = 0;
1132
- return Float64Array.from(items, (value) => sum.add(+(accessor(value, i++, items) || 0)));
1133
- }
1134
- function mean(items, accessor) {
1249
+ return Float64Array.from(
1250
+ items,
1251
+ // we do not actually need to coerce the Adder to number,
1252
+ // as @Fil demonstrated here: https://github.com/pbeshai/tidy/pull/5
1253
+ // so we can just tell typescript to be quiet.
1254
+ (value) => sum.add(+(accessor(value, i++, items) || 0))
1255
+ );
1256
+ }
1257
+ function mean$1(items, accessor) {
1135
1258
  let n = 0;
1259
+ const sum = new d3Array.Adder();
1136
1260
  for (let i = 0; i < items.length; ++i) {
1137
1261
  const value = accessor(items[i], i, items);
1138
1262
  if (+value === value) {
1263
+ sum.add(+value);
1139
1264
  n += 1;
1140
1265
  }
1141
1266
  }
1142
- return n ? d3Array.fsum(items, accessor) / n : void 0;
1267
+ return n ? +sum / n : void 0;
1143
1268
  }
1144
1269
 
1145
1270
  function cumsum(key) {
@@ -1148,7 +1273,7 @@
1148
1273
  }
1149
1274
 
1150
1275
  function roll(width, rollFn, options) {
1151
- const {partial = false, align = "right"} = options != null ? options : {};
1276
+ const { partial = false, align = "right" } = options != null ? options : {};
1152
1277
  const halfWidth = Math.floor(width / 2);
1153
1278
  return (items) => {
1154
1279
  return items.map((_, i) => {
@@ -1165,7 +1290,7 @@
1165
1290
 
1166
1291
  function lag(key, options) {
1167
1292
  const keyFn = typeof key === "function" ? key : (d) => d[key];
1168
- const {n = 1, default: defaultValue} = options != null ? options : {};
1293
+ const { n = 1, default: defaultValue } = options != null ? options : {};
1169
1294
  return (items) => {
1170
1295
  return items.map((_, i) => {
1171
1296
  const lagItem = items[i - n];
@@ -1176,7 +1301,7 @@
1176
1301
 
1177
1302
  function lead(key, options) {
1178
1303
  const keyFn = typeof key === "function" ? key : (d) => d[key];
1179
- const {n = 1, default: defaultValue} = options != null ? options : {};
1304
+ const { n = 1, default: defaultValue } = options != null ? options : {};
1180
1305
  return (items) => {
1181
1306
  return items.map((_, i) => {
1182
1307
  const leadItem = items[i + n];
@@ -1203,9 +1328,9 @@
1203
1328
  return (items) => d3Array.max(items, keyFn);
1204
1329
  }
1205
1330
 
1206
- function mean$1(key) {
1331
+ function mean(key) {
1207
1332
  const keyFn = typeof key === "function" ? key : (d) => d[key];
1208
- return (items) => mean(items, keyFn);
1333
+ return (items) => mean$1(items, keyFn);
1209
1334
  }
1210
1335
 
1211
1336
  function meanRate(numerator, denominator) {
@@ -1214,7 +1339,7 @@
1214
1339
  return (items) => {
1215
1340
  const numerator2 = d3Array.fsum(items, numeratorFn);
1216
1341
  const denominator2 = d3Array.fsum(items, denominatorFn);
1217
- return rate(numerator2, denominator2);
1342
+ return rate$1(numerator2, denominator2);
1218
1343
  };
1219
1344
  }
1220
1345
 
@@ -1236,7 +1361,7 @@
1236
1361
  function nDistinct(key, options = {}) {
1237
1362
  const keyFn = typeof key === "function" ? key : (d) => d[key];
1238
1363
  return (items) => {
1239
- const uniques = new Map();
1364
+ const uniques = /* @__PURE__ */ new Set();
1240
1365
  let count = 0;
1241
1366
  let i = 0;
1242
1367
  for (const item of items) {
@@ -1246,7 +1371,7 @@
1246
1371
  continue;
1247
1372
  }
1248
1373
  count += 1;
1249
- uniques.set(value, true);
1374
+ uniques.add(value);
1250
1375
  }
1251
1376
  }
1252
1377
  return count;
@@ -1308,7 +1433,7 @@
1308
1433
 
1309
1434
  function negate(selectors) {
1310
1435
  return (items) => {
1311
- let keySet = new Set();
1436
+ let keySet = /* @__PURE__ */ new Set();
1312
1437
  for (const selector of singleOrArray(selectors)) {
1313
1438
  if (typeof selector === "function") {
1314
1439
  const keys2 = selector(items);
@@ -1319,7 +1444,7 @@
1319
1444
  keySet.add(selector);
1320
1445
  }
1321
1446
  }
1322
- const keys = Array.from(keySet).map((key) => `-${key}`);
1447
+ const keys = Array.from(keySet).map((key) => `-${String(key)}`);
1323
1448
  return keys;
1324
1449
  };
1325
1450
  }
@@ -1357,7 +1482,7 @@
1357
1482
  exports.map = map;
1358
1483
  exports.matches = matches;
1359
1484
  exports.max = max;
1360
- exports.mean = mean$1;
1485
+ exports.mean = mean;
1361
1486
  exports.meanRate = meanRate;
1362
1487
  exports.median = median;
1363
1488
  exports.min = min;
@@ -1370,7 +1495,7 @@
1370
1495
  exports.pick = select;
1371
1496
  exports.pivotLonger = pivotLonger;
1372
1497
  exports.pivotWider = pivotWider;
1373
- exports.rate = rate$1;
1498
+ exports.rate = rate;
1374
1499
  exports.rename = rename;
1375
1500
  exports.replaceNully = replaceNully;
1376
1501
  exports.roll = roll;
@@ -1401,7 +1526,5 @@
1401
1526
  exports.vectorSeqDate = vectorSeqDate;
1402
1527
  exports.when = when;
1403
1528
 
1404
- Object.defineProperty(exports, '__esModule', { value: true });
1405
-
1406
- })));
1529
+ }));
1407
1530
  //# sourceMappingURL=tidy.js.map