@oscarpalmer/atoms 0.143.0 → 0.144.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 (49) hide show
  1. package/dist/array/filter.js +5 -1
  2. package/dist/array/partition.js +6 -0
  3. package/dist/array/range.js +6 -0
  4. package/dist/array/select.js +5 -0
  5. package/dist/array/toggle.js +5 -0
  6. package/dist/array/unique.js +1 -1
  7. package/dist/array/update.js +5 -0
  8. package/dist/atoms.full.js +94 -17
  9. package/dist/index.js +7 -2
  10. package/dist/internal/array/callbacks.js +1 -1
  11. package/dist/internal/array/find.js +23 -11
  12. package/dist/internal/array/update.js +22 -0
  13. package/dist/math.js +24 -3
  14. package/dist/value/merge.js +3 -1
  15. package/package.json +21 -1
  16. package/src/array/exists.ts +7 -8
  17. package/src/array/filter.ts +32 -9
  18. package/src/array/find.ts +6 -6
  19. package/src/array/index-of.ts +7 -8
  20. package/src/array/partition.ts +56 -0
  21. package/src/array/range.ts +35 -0
  22. package/src/array/select.ts +92 -0
  23. package/src/array/toggle.ts +40 -0
  24. package/src/array/unique.ts +6 -6
  25. package/src/array/update.ts +40 -0
  26. package/src/index.ts +5 -0
  27. package/src/internal/array/callbacks.ts +1 -1
  28. package/src/internal/array/find.ts +35 -29
  29. package/src/internal/array/update.ts +52 -0
  30. package/src/internal/math/aggregate.ts +2 -2
  31. package/src/math.ts +33 -5
  32. package/src/value/merge.ts +10 -6
  33. package/types/array/exists.d.ts +2 -2
  34. package/types/array/filter.d.ts +10 -2
  35. package/types/array/find.d.ts +2 -2
  36. package/types/array/index-of.d.ts +2 -2
  37. package/types/array/partition.d.ts +31 -0
  38. package/types/array/range.d.ts +20 -0
  39. package/types/array/select.d.ts +43 -0
  40. package/types/array/toggle.d.ts +24 -0
  41. package/types/array/unique.d.ts +2 -2
  42. package/types/array/update.d.ts +24 -0
  43. package/types/index.d.ts +5 -0
  44. package/types/internal/array/callbacks.d.ts +1 -0
  45. package/types/internal/array/find.d.ts +5 -2
  46. package/types/internal/array/update.d.ts +1 -0
  47. package/types/internal/math/aggregate.d.ts +1 -1
  48. package/types/math.d.ts +15 -1
  49. package/types/value/merge.d.ts +5 -4
@@ -1,5 +1,9 @@
1
1
  import { findValues } from "../internal/array/find.js";
2
2
  function filter(array, ...parameters) {
3
- return findValues("all", array, parameters);
3
+ return findValues("all", array, parameters).matched;
4
+ }
5
+ filter.remove = removeFiltered;
6
+ function removeFiltered(array, ...parameters) {
7
+ return findValues("all", array, parameters).notMatched;
4
8
  }
5
9
  export { filter };
@@ -0,0 +1,6 @@
1
+ import { findValues } from "../internal/array/find.js";
2
+ function partition(array, ...parameters) {
3
+ const { matched, notMatched } = findValues("all", array, parameters);
4
+ return [matched, notMatched];
5
+ }
6
+ export { partition };
@@ -0,0 +1,6 @@
1
+ function range(length, value) {
2
+ if (typeof length !== "number" || length <= 0) return [];
3
+ const isFunction = typeof value === "function";
4
+ return Array.from({ length }, (_, index) => isFunction ? value(index) : value ?? index);
5
+ }
6
+ export { range };
@@ -0,0 +1,5 @@
1
+ import { findValues } from "../internal/array/find.js";
2
+ function select(array, ...parameters) {
3
+ return findValues("all", array, parameters, parameters.pop()).matched;
4
+ }
5
+ export { select };
@@ -0,0 +1,5 @@
1
+ import { updateInArray } from "../internal/array/update.js";
2
+ function toggle(array, values, key) {
3
+ return updateInArray(array, values, key, false);
4
+ }
5
+ export { toggle };
@@ -1,6 +1,6 @@
1
1
  import { findValues } from "../internal/array/find.js";
2
2
  function unique(array, key) {
3
3
  if (!Array.isArray(array)) return [];
4
- return array.length > 1 ? findValues("unique", array, [key, void 0]) : array;
4
+ return array.length > 1 ? findValues("unique", array, [key, void 0]).matched : array;
5
5
  }
6
6
  export { unique };
@@ -0,0 +1,5 @@
1
+ import { updateInArray } from "../internal/array/update.js";
2
+ function update(array, values, key) {
3
+ return updateInArray(array, values, key, true);
4
+ }
5
+ export { update };
@@ -57,27 +57,39 @@ function findValueInArray(array, callback, value, findIndex) {
57
57
  }
58
58
  return findIndex ? -1 : void 0;
59
59
  }
60
- function findValues(type, array, parameters) {
61
- if (!Array.isArray(array)) return [];
62
- if (array.length === 0) return [];
60
+ function findValues(type, array, parameters, mapper) {
61
+ const result = {
62
+ matched: [],
63
+ notMatched: []
64
+ };
65
+ if (!Array.isArray(array) || array.length === 0) return result;
63
66
  const { length } = array;
64
67
  const { bool, key, value } = getParameters(parameters);
65
68
  const callbacks = getArrayCallbacks(bool, key);
66
- if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) return [...new Set(array)];
67
- if (callbacks?.bool != null) return array.filter(callbacks.bool);
68
- if (type === "all" && key == null) return array.filter((item) => item === value);
69
+ if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) {
70
+ result.matched = [...new Set(array)];
71
+ return result;
72
+ }
73
+ const mapCallback = typeof mapper === "function" ? mapper : void 0;
74
+ if (callbacks?.bool != null || type === "all" && key == null) {
75
+ const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
76
+ for (let index = 0; index < length; index += 1) {
77
+ const item = array[index];
78
+ if (callback(item, index, array)) result.matched.push(mapCallback?.(item, index, array) ?? item);
79
+ else result.notMatched.push(item);
80
+ }
81
+ return result;
82
+ }
69
83
  const keys = /* @__PURE__ */ new Set();
70
- const values = [];
71
84
  for (let index = 0; index < length; index += 1) {
72
85
  const item = array[index];
73
86
  const keyed = callbacks?.keyed?.(item, index, array) ?? item;
74
87
  if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
75
88
  keys.add(keyed);
76
- values.push(item);
77
- }
89
+ result.matched.push(mapCallback?.(item, index, array) ?? item);
90
+ } else result.notMatched.push(item);
78
91
  }
79
- keys.clear();
80
- return values;
92
+ return result;
81
93
  }
82
94
  function getParameters(original) {
83
95
  const { length } = original;
@@ -93,7 +105,11 @@ function exists(array, ...parameters) {
93
105
  return findValue("index", array, parameters) > -1;
94
106
  }
95
107
  function filter(array, ...parameters) {
96
- return findValues("all", array, parameters);
108
+ return findValues("all", array, parameters).matched;
109
+ }
110
+ filter.remove = removeFiltered;
111
+ function removeFiltered(array, ...parameters) {
112
+ return findValues("all", array, parameters).notMatched;
97
113
  }
98
114
  function find(array, ...parameters) {
99
115
  return findValue("value", array, parameters);
@@ -257,6 +273,10 @@ function insertValues(type, array, items, start, deleteCount) {
257
273
  function insert(array, indexOrItems, items) {
258
274
  return insertValues("insert", array, items == null ? indexOrItems : items, typeof indexOrItems === "number" ? indexOrItems : array?.length, 0);
259
275
  }
276
+ function partition(array, ...parameters) {
277
+ const { matched, notMatched } = findValues("all", array, parameters);
278
+ return [matched, notMatched];
279
+ }
260
280
  /**
261
281
  * Push items into an array _(at the end)_
262
282
  * @param array Original array
@@ -266,6 +286,14 @@ function insert(array, indexOrItems, items) {
266
286
  function push(array, pushed) {
267
287
  return insertValues("push", array, pushed, array.length, 0);
268
288
  }
289
+ function range(length, value) {
290
+ if (typeof length !== "number" || length <= 0) return [];
291
+ const isFunction = typeof value === "function";
292
+ return Array.from({ length }, (_, index) => isFunction ? value(index) : value ?? index);
293
+ }
294
+ function select(array, ...parameters) {
295
+ return findValues("all", array, parameters, parameters.pop()).matched;
296
+ }
269
297
  function aggregate(type, array, key) {
270
298
  const length = Array.isArray(array) ? array.length : 0;
271
299
  if (length === 0) return {
@@ -590,9 +618,35 @@ function toSet(array, value) {
590
618
  for (let index = 0; index < length; index += 1) set.add(callbacks.value(array[index], index, array));
591
619
  return set;
592
620
  }
621
+ function updateInArray(array, items, key, replace) {
622
+ if (!Array.isArray(array)) return [];
623
+ const itemsIsArray = Array.isArray(items);
624
+ if (array.length === 0 || !itemsIsArray) {
625
+ if (itemsIsArray) array.push(...items);
626
+ return array;
627
+ }
628
+ const { length } = items;
629
+ if (length === 0) return array;
630
+ const callback = getArrayCallback(key);
631
+ for (let valuesIndex = 0; valuesIndex < length; valuesIndex += 1) {
632
+ const item = items[valuesIndex];
633
+ const value = callback?.(item) ?? item;
634
+ const arrayIndex = callback == null ? array.indexOf(value) : array.findIndex((arrayItem, arrayIndex) => callback(arrayItem, arrayIndex, array) === value);
635
+ if (arrayIndex === -1) array.push(item);
636
+ else if (replace) array[arrayIndex] = item;
637
+ else array.splice(arrayIndex, 1);
638
+ }
639
+ return array;
640
+ }
641
+ function toggle(array, values, key) {
642
+ return updateInArray(array, values, key, false);
643
+ }
593
644
  function unique(array, key) {
594
645
  if (!Array.isArray(array)) return [];
595
- return array.length > 1 ? findValues("unique", array, [key, void 0]) : array;
646
+ return array.length > 1 ? findValues("unique", array, [key, void 0]).matched : array;
647
+ }
648
+ function update(array, values, key) {
649
+ return updateInArray(array, values, key, true);
596
650
  }
597
651
  function getLimiter(callback, throttler, time) {
598
652
  const interval = typeof time === "number" && time >= frame_rate_default ? time : frame_rate_default;
@@ -1583,10 +1637,12 @@ function setChanges(parameters) {
1583
1637
  function getMergeOptions(options) {
1584
1638
  const actual = {
1585
1639
  replaceableObjects: void 0,
1640
+ skipNullableAny: false,
1586
1641
  skipNullableInArrays: false
1587
1642
  };
1588
1643
  if (typeof options !== "object" || options == null) return actual;
1589
1644
  actual.replaceableObjects = getReplaceableObjects(options.replaceableObjects);
1645
+ actual.skipNullableAny = options.skipNullableAny === true;
1590
1646
  actual.skipNullableInArrays = options.skipNullableInArrays === true;
1591
1647
  return actual;
1592
1648
  }
@@ -1629,7 +1685,7 @@ function mergeObjects(values, options, prefix) {
1629
1685
  const full = join([prefix, key], ".");
1630
1686
  const next = item[key];
1631
1687
  const previous = merged[key];
1632
- if (isArray && options.skipNullableInArrays && next == null) continue;
1688
+ if (next == null && (options.skipNullableAny || isArray && options.skipNullableInArrays)) continue;
1633
1689
  if (isArrayOrPlainObject(next) && isArrayOrPlainObject(previous) && !(options.replaceableObjects?.(full) ?? false)) merged[key] = mergeValues([previous, next], options, false, full);
1634
1690
  else merged[key] = next;
1635
1691
  }
@@ -2746,6 +2802,15 @@ function average(array, key) {
2746
2802
  const aggregated = aggregate("average", array, key);
2747
2803
  return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
2748
2804
  }
2805
+ /**
2806
+ * Round a number up
2807
+ * @param value Number to round up
2808
+ * @param decimals Number of decimal places to round to _(defaults to `0`)_
2809
+ * @returns Rounded number, or `NaN` if the value if unable to be rounded
2810
+ */
2811
+ function ceil(value, decimals) {
2812
+ return roundNumber(Math.ceil, value, decimals);
2813
+ }
2749
2814
  function count(array, key, value) {
2750
2815
  if (!Array.isArray(array)) return NaN;
2751
2816
  const { length } = array;
@@ -2758,6 +2823,15 @@ function count(array, key, value) {
2758
2823
  }
2759
2824
  return counted;
2760
2825
  }
2826
+ /**
2827
+ * Round a number down
2828
+ * @param value Number to round down
2829
+ * @param decimals Number of decimal places to round to _(defaults to `0`)_
2830
+ * @returns Rounded number, or `NaN` if the value if unable to be rounded
2831
+ */
2832
+ function floor(value, decimals) {
2833
+ return roundNumber(Math.floor, value, decimals);
2834
+ }
2761
2835
  function median(array, key) {
2762
2836
  let length = Array.isArray(array) ? array.length : 0;
2763
2837
  if (!Array.isArray(array) || length === 0) return NaN;
@@ -2784,10 +2858,13 @@ function min(array, key) {
2784
2858
  * @returns Rounded number, or `NaN` if the value if unable to be rounded
2785
2859
  */
2786
2860
  function round(value, decimals) {
2861
+ return roundNumber(Math.round, value, decimals);
2862
+ }
2863
+ function roundNumber(callback, value, decimals) {
2787
2864
  if (typeof value !== "number") return NaN;
2788
- if (typeof decimals !== "number" || decimals < 1) return Math.round(value);
2865
+ if (typeof decimals !== "number" || decimals < 1) return callback(value);
2789
2866
  const mod = 10 ** decimals;
2790
- return Math.round((value + Number.EPSILON) * mod) / mod;
2867
+ return callback((value + Number.EPSILON) * mod) / mod;
2791
2868
  }
2792
2869
  function sum(array, key) {
2793
2870
  return getAggregated("sum", array, key);
@@ -3455,4 +3532,4 @@ var SizedSet = class extends Set {
3455
3532
  }
3456
3533
  }
3457
3534
  };
3458
- export { CancelablePromise, frame_rate_default as FRAME_RATE_MS, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, fromQuery, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, pascalCase, pick, promises, push, queue, rgbToHex, rgbToHsl, rgbToHsla, round, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, titleCase, toMap, toQuery, toRecord, toSet, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, upperCase, words };
3535
+ export { CancelablePromise, frame_rate_default as FRAME_RATE_MS, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, fromQuery, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, promises, push, queue, range, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
package/dist/index.js CHANGED
@@ -8,7 +8,10 @@ import { groupBy } from "./array/group-by.js";
8
8
  import { indexOf } from "./array/index-of.js";
9
9
  import { chunk } from "./internal/array/chunk.js";
10
10
  import { insert } from "./array/insert.js";
11
+ import { partition } from "./array/partition.js";
11
12
  import { push } from "./array/push.js";
13
+ import { range } from "./array/range.js";
14
+ import { select } from "./array/select.js";
12
15
  import { max } from "./internal/math/aggregate.js";
13
16
  import { compact } from "./internal/array/compact.js";
14
17
  import { getString, ignoreKey, join, tryDecode, tryEncode, words } from "./internal/string.js";
@@ -18,7 +21,9 @@ import { splice } from "./array/splice.js";
18
21
  import { toMap } from "./array/to-map.js";
19
22
  import { toRecord } from "./array/to-record.js";
20
23
  import { toSet } from "./array/to-set.js";
24
+ import { toggle } from "./array/toggle.js";
21
25
  import { unique } from "./array/unique.js";
26
+ import { update } from "./array/update.js";
22
27
  import { noop } from "./internal/function/misc.js";
23
28
  import { beacon } from "./beacon.js";
24
29
  import { between, clamp, getNumber } from "./internal/number.js";
@@ -51,11 +56,11 @@ import { smush } from "./value/smush.js";
51
56
  import { unsmush } from "./value/unsmush.js";
52
57
  import { isEmpty, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumerical, isObject, isPrimitive } from "./is.js";
53
58
  import { logger } from "./logger.js";
54
- import { average, count, median, min, round, sum } from "./math.js";
59
+ import { average, ceil, count, floor, median, min, round, sum } from "./math.js";
55
60
  import { CancelablePromise, PromiseTimeoutError, attemptPromise, cancelable, delay, isFulfilled, isRejected, promises, timed } from "./promise.js";
56
61
  import { fromQuery, toQuery } from "./query.js";
57
62
  import { QueueError, queue } from "./queue.js";
58
63
  import { getRandomBoolean, getRandomCharacters, getRandomColor, getRandomHex, getRandomItem, getRandomItems } from "./random.js";
59
64
  import { attempt, error, isError, isOk, isResult, ok, unwrap } from "./result.js";
60
65
  import { SizedSet } from "./sized/set.js";
61
- export { CancelablePromise, frame_rate_default as FRAME_RATE_MS, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, fromQuery, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, pascalCase, pick, promises, push, queue, rgbToHex, rgbToHsl, rgbToHsla, round, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, titleCase, toMap, toQuery, toRecord, toSet, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, upperCase, words };
66
+ export { CancelablePromise, frame_rate_default as FRAME_RATE_MS, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, fromQuery, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, promises, push, queue, range, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
@@ -13,4 +13,4 @@ function getArrayCallbacks(bool, key, value) {
13
13
  value: getArrayCallback(value)
14
14
  };
15
15
  }
16
- export { getArrayCallbacks };
16
+ export { getArrayCallback, getArrayCallbacks };
@@ -19,27 +19,39 @@ function findValueInArray(array, callback, value, findIndex) {
19
19
  }
20
20
  return findIndex ? -1 : void 0;
21
21
  }
22
- function findValues(type, array, parameters) {
23
- if (!Array.isArray(array)) return [];
24
- if (array.length === 0) return [];
22
+ function findValues(type, array, parameters, mapper) {
23
+ const result = {
24
+ matched: [],
25
+ notMatched: []
26
+ };
27
+ if (!Array.isArray(array) || array.length === 0) return result;
25
28
  const { length } = array;
26
29
  const { bool, key, value } = getParameters(parameters);
27
30
  const callbacks = getArrayCallbacks(bool, key);
28
- if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) return [...new Set(array)];
29
- if (callbacks?.bool != null) return array.filter(callbacks.bool);
30
- if (type === "all" && key == null) return array.filter((item) => item === value);
31
+ if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) {
32
+ result.matched = [...new Set(array)];
33
+ return result;
34
+ }
35
+ const mapCallback = typeof mapper === "function" ? mapper : void 0;
36
+ if (callbacks?.bool != null || type === "all" && key == null) {
37
+ const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
38
+ for (let index = 0; index < length; index += 1) {
39
+ const item = array[index];
40
+ if (callback(item, index, array)) result.matched.push(mapCallback?.(item, index, array) ?? item);
41
+ else result.notMatched.push(item);
42
+ }
43
+ return result;
44
+ }
31
45
  const keys = /* @__PURE__ */ new Set();
32
- const values = [];
33
46
  for (let index = 0; index < length; index += 1) {
34
47
  const item = array[index];
35
48
  const keyed = callbacks?.keyed?.(item, index, array) ?? item;
36
49
  if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
37
50
  keys.add(keyed);
38
- values.push(item);
39
- }
51
+ result.matched.push(mapCallback?.(item, index, array) ?? item);
52
+ } else result.notMatched.push(item);
40
53
  }
41
- keys.clear();
42
- return values;
54
+ return result;
43
55
  }
44
56
  function getParameters(original) {
45
57
  const { length } = original;
@@ -0,0 +1,22 @@
1
+ import { getArrayCallback } from "./callbacks.js";
2
+ function updateInArray(array, items, key, replace) {
3
+ if (!Array.isArray(array)) return [];
4
+ const itemsIsArray = Array.isArray(items);
5
+ if (array.length === 0 || !itemsIsArray) {
6
+ if (itemsIsArray) array.push(...items);
7
+ return array;
8
+ }
9
+ const { length } = items;
10
+ if (length === 0) return array;
11
+ const callback = getArrayCallback(key);
12
+ for (let valuesIndex = 0; valuesIndex < length; valuesIndex += 1) {
13
+ const item = items[valuesIndex];
14
+ const value = callback?.(item) ?? item;
15
+ const arrayIndex = callback == null ? array.indexOf(value) : array.findIndex((arrayItem, arrayIndex) => callback(arrayItem, arrayIndex, array) === value);
16
+ if (arrayIndex === -1) array.push(item);
17
+ else if (replace) array[arrayIndex] = item;
18
+ else array.splice(arrayIndex, 1);
19
+ }
20
+ return array;
21
+ }
22
+ export { updateInArray };
package/dist/math.js CHANGED
@@ -4,6 +4,15 @@ function average(array, key) {
4
4
  const aggregated = aggregate("average", array, key);
5
5
  return aggregated.count > 0 ? aggregated.value / aggregated.count : NaN;
6
6
  }
7
+ /**
8
+ * Round a number up
9
+ * @param value Number to round up
10
+ * @param decimals Number of decimal places to round to _(defaults to `0`)_
11
+ * @returns Rounded number, or `NaN` if the value if unable to be rounded
12
+ */
13
+ function ceil(value, decimals) {
14
+ return roundNumber(Math.ceil, value, decimals);
15
+ }
7
16
  function count(array, key, value) {
8
17
  if (!Array.isArray(array)) return NaN;
9
18
  const { length } = array;
@@ -16,6 +25,15 @@ function count(array, key, value) {
16
25
  }
17
26
  return counted;
18
27
  }
28
+ /**
29
+ * Round a number down
30
+ * @param value Number to round down
31
+ * @param decimals Number of decimal places to round to _(defaults to `0`)_
32
+ * @returns Rounded number, or `NaN` if the value if unable to be rounded
33
+ */
34
+ function floor(value, decimals) {
35
+ return roundNumber(Math.floor, value, decimals);
36
+ }
19
37
  function median(array, key) {
20
38
  let length = Array.isArray(array) ? array.length : 0;
21
39
  if (!Array.isArray(array) || length === 0) return NaN;
@@ -42,12 +60,15 @@ function min(array, key) {
42
60
  * @returns Rounded number, or `NaN` if the value if unable to be rounded
43
61
  */
44
62
  function round(value, decimals) {
63
+ return roundNumber(Math.round, value, decimals);
64
+ }
65
+ function roundNumber(callback, value, decimals) {
45
66
  if (typeof value !== "number") return NaN;
46
- if (typeof decimals !== "number" || decimals < 1) return Math.round(value);
67
+ if (typeof decimals !== "number" || decimals < 1) return callback(value);
47
68
  const mod = 10 ** decimals;
48
- return Math.round((value + Number.EPSILON) * mod) / mod;
69
+ return callback((value + Number.EPSILON) * mod) / mod;
49
70
  }
50
71
  function sum(array, key) {
51
72
  return getAggregated("sum", array, key);
52
73
  }
53
- export { average, count, max, median, min, round, sum };
74
+ export { average, ceil, count, floor, max, median, min, round, sum };
@@ -3,10 +3,12 @@ import { join } from "../internal/string.js";
3
3
  function getMergeOptions(options) {
4
4
  const actual = {
5
5
  replaceableObjects: void 0,
6
+ skipNullableAny: false,
6
7
  skipNullableInArrays: false
7
8
  };
8
9
  if (typeof options !== "object" || options == null) return actual;
9
10
  actual.replaceableObjects = getReplaceableObjects(options.replaceableObjects);
11
+ actual.skipNullableAny = options.skipNullableAny === true;
10
12
  actual.skipNullableInArrays = options.skipNullableInArrays === true;
11
13
  return actual;
12
14
  }
@@ -49,7 +51,7 @@ function mergeObjects(values, options, prefix) {
49
51
  const full = join([prefix, key], ".");
50
52
  const next = item[key];
51
53
  const previous = merged[key];
52
- if (isArray && options.skipNullableInArrays && next == null) continue;
54
+ if (next == null && (options.skipNullableAny || isArray && options.skipNullableInArrays)) continue;
53
55
  if (isArrayOrPlainObject(next) && isArrayOrPlainObject(previous) && !(options.replaceableObjects?.(full) ?? false)) merged[key] = mergeValues([previous, next], options, false, full);
54
56
  else merged[key] = next;
55
57
  }
package/package.json CHANGED
@@ -62,10 +62,22 @@
62
62
  "types": "./types/array/insert.d.ts",
63
63
  "default": "./dist/array/insert.js"
64
64
  },
65
+ "./array/partition": {
66
+ "types": "./types/array/partition.d.ts",
67
+ "default": "./dist/array/partition.js"
68
+ },
65
69
  "./array/push": {
66
70
  "types": "./types/array/push.d.ts",
67
71
  "default": "./dist/array/push.js"
68
72
  },
73
+ "./array/range": {
74
+ "types": "./types/array/range.d.ts",
75
+ "default": "./dist/array/range.js"
76
+ },
77
+ "./array/select": {
78
+ "types": "./types/array/select.d.ts",
79
+ "default": "./dist/array/select.js"
80
+ },
69
81
  "./array/sort": {
70
82
  "types": "./types/array/sort.d.ts",
71
83
  "default": "./dist/array/sort.js"
@@ -86,10 +98,18 @@
86
98
  "types": "./types/array/to-set.d.ts",
87
99
  "default": "./dist/array/to-set.js"
88
100
  },
101
+ "./array/toggle": {
102
+ "types": "./types/array/toggle.d.ts",
103
+ "default": "./dist/array/toggle.js"
104
+ },
89
105
  "./array/unique": {
90
106
  "types": "./types/array/unique.d.ts",
91
107
  "default": "./dist/array/unique.js"
92
108
  },
109
+ "./array/update": {
110
+ "types": "./types/array/update.d.ts",
111
+ "default": "./dist/array/update.js"
112
+ },
93
113
  "./beacon": {
94
114
  "types": "./types/beacon.d.ts",
95
115
  "default": "./dist/beacon.js"
@@ -236,5 +256,5 @@
236
256
  },
237
257
  "type": "module",
238
258
  "types": "./types/index.d.ts",
239
- "version": "0.143.0"
259
+ "version": "0.144.0"
240
260
  }
@@ -10,11 +10,10 @@ import type {PlainObject} from '../models';
10
10
  * @param value Value to match against
11
11
  * @returns `true` if the item exists in the array, otherwise `false`
12
12
  */
13
- export function exists<Item>(
14
- array: Item[],
15
- callback: (item: Item, index: number, array: Item[]) => unknown,
16
- value: unknown,
17
- ): boolean;
13
+ export function exists<
14
+ Item,
15
+ Callback extends (item: Item, index: number, array: Item[]) => unknown,
16
+ >(array: Item[], callback: Callback, value: ReturnType<Callback>): boolean;
18
17
 
19
18
  /**
20
19
  * Does an item with a specific value exist in the array?
@@ -23,10 +22,10 @@ export function exists<Item>(
23
22
  * @param value Value to match against
24
23
  * @returns `true` if the item exists in the array, otherwise `false`
25
24
  */
26
- export function exists<Item extends PlainObject>(
25
+ export function exists<Item extends PlainObject, Key extends keyof Item>(
27
26
  array: Item[],
28
- key: keyof Item,
29
- value: unknown,
27
+ key: Key,
28
+ value: Item[Key],
30
29
  ): boolean;
31
30
 
32
31
  /**
@@ -10,11 +10,10 @@ import type {PlainObject} from '../models';
10
10
  * @param value Value to match against
11
11
  * @returns Filtered array of items
12
12
  */
13
- export function filter<Item>(
14
- array: Item[],
15
- callback: (item: Item, index: number, array: Item[]) => unknown,
16
- value: unknown,
17
- ): Item[];
13
+ export function filter<
14
+ Item,
15
+ Callback extends (item: Item, index: number, array: Item[]) => unknown,
16
+ >(array: Item[], callback: Callback, value: ReturnType<Callback>): Item[];
18
17
 
19
18
  /**
20
19
  * Get a filtered array of items
@@ -23,10 +22,10 @@ export function filter<Item>(
23
22
  * @param value Value to match against
24
23
  * @returns Filtered array of items
25
24
  */
26
- export function filter<Item extends PlainObject>(
25
+ export function filter<Item extends PlainObject, Key extends keyof Item>(
27
26
  array: Item[],
28
- key: keyof Item,
29
- value: unknown,
27
+ key: Key,
28
+ value: Item[Key],
30
29
  ): Item[];
31
30
 
32
31
  /**
@@ -49,7 +48,31 @@ export function filter<Item>(
49
48
  export function filter<Item>(array: Item[], item: Item): Item[];
50
49
 
51
50
  export function filter(array: unknown[], ...parameters: unknown[]): unknown[] {
52
- return findValues('all', array, parameters);
51
+ return findValues('all', array, parameters).matched;
52
+ }
53
+
54
+ filter.remove = removeFiltered;
55
+
56
+ function removeFiltered<
57
+ Item,
58
+ Callback extends (item: Item, index: number, array: Item[]) => unknown,
59
+ >(array: Item[], callback: Callback, value: ReturnType<Callback>): unknown[];
60
+
61
+ function removeFiltered<Item extends PlainObject, Key extends keyof Item>(
62
+ array: Item[],
63
+ key: Key,
64
+ value: Item[Key],
65
+ ): unknown[];
66
+
67
+ function removeFiltered<Item>(
68
+ array: Item[],
69
+ filter: (item: Item, index: number, array: Item[]) => boolean,
70
+ ): unknown[];
71
+
72
+ function removeFiltered<Item>(array: Item[], item: Item): unknown[];
73
+
74
+ function removeFiltered(array: unknown[], ...parameters: unknown[]): unknown[] {
75
+ return findValues('all', array, parameters).notMatched;
53
76
  }
54
77
 
55
78
  // #endregion
package/src/array/find.ts CHANGED
@@ -10,10 +10,10 @@ import type {PlainObject} from '../models';
10
10
  * @param value Value to match against
11
11
  * @returns First item that matches the value, or `undefined` if no match is found
12
12
  */
13
- export function find<Item>(
13
+ export function find<Item, Callback extends (item: Item, index: number, array: Item[]) => unknown>(
14
14
  array: Item[],
15
- callback: (item: Item, index: number, array: Item[]) => unknown,
16
- value: unknown,
15
+ callback: Callback,
16
+ value: ReturnType<Callback>,
17
17
  ): Item | undefined;
18
18
 
19
19
  /**
@@ -23,10 +23,10 @@ export function find<Item>(
23
23
  * @param value Value to match against
24
24
  * @returns First item that matches the value, or `undefined` if no match is found
25
25
  */
26
- export function find<Item extends PlainObject>(
26
+ export function find<Item extends PlainObject, Key extends keyof Item>(
27
27
  array: Item[],
28
- key: keyof Item,
29
- value: unknown,
28
+ key: Key,
29
+ value: Item[Key],
30
30
  ): Item | undefined;
31
31
 
32
32
  /**
@@ -10,11 +10,10 @@ import type {PlainObject} from '../models';
10
10
  * @param value Value to match against
11
11
  * @returns Index of the first matching item, or `-1` if no match is found
12
12
  */
13
- export function indexOf<Item>(
14
- array: Item[],
15
- callback: (item: Item, index: number, array: Item[]) => unknown,
16
- value: unknown,
17
- ): number;
13
+ export function indexOf<
14
+ Item,
15
+ Callback extends (item: Item, index: number, array: Item[]) => unknown,
16
+ >(array: Item[], callback: Callback, value: ReturnType<Callback>): number;
18
17
 
19
18
  /**
20
19
  * Get the index of the first matching item by key
@@ -23,10 +22,10 @@ export function indexOf<Item>(
23
22
  * @param value Value to match against
24
23
  * @returns Index of the first matching item, or `-1` if no match is found
25
24
  */
26
- export function indexOf<Item extends PlainObject>(
25
+ export function indexOf<Item extends PlainObject, Key extends keyof Item>(
27
26
  array: Item[],
28
- key: keyof Item,
29
- value: unknown,
27
+ key: Key,
28
+ value: Item[Key],
30
29
  ): number;
31
30
 
32
31
  /**