@oscarpalmer/atoms 0.195.1 → 0.196.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -31,13 +31,6 @@ type CancelableCallback<Callback extends GenericCallback> = Callback & {
31
31
  * A generic class constructor
32
32
  */
33
33
  type Constructor<Instance = unknown> = new (...args: any[]) => Instance;
34
- /**
35
- * Position of an event
36
- */
37
- type EventPosition = {
38
- x: number;
39
- y: number;
40
- };
41
34
  /**
42
35
  * A generic async callback function
43
36
  */
@@ -7863,16 +7856,17 @@ declare const Logger: Logger;
7863
7856
  * max(
7864
7857
  * [{id: 1, value: 10}, {id: 2, value: 20}],
7865
7858
  * item => item.value,
7866
- * ); // => 20
7859
+ * ); // => [{id: 2, value: 20}]
7867
7860
  *
7868
- * max([], item => item.value); // => Number.NaN
7861
+ * max([], item => item.value); // => []
7869
7862
  * ```
7870
7863
  *
7871
7864
  * @param items List of items
7872
7865
  * @param callback Callback to get an item's value
7873
- * @returns Maximum value, or `Number.NaN` if no maximum can be found
7866
+ * @param first Return only the first item with the maximum value
7867
+ * @returns Item with the maximum value, or `undefined` if no maximum can be found
7874
7868
  */
7875
- declare function max<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): number;
7869
+ declare function max<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number, first: true): Item | undefined;
7876
7870
  /**
7877
7871
  * Get the maximum value from a list of items
7878
7872
  *
@@ -7881,16 +7875,53 @@ declare function max<Item>(items: Item[], callback: (item: Item, index: number,
7881
7875
  * max(
7882
7876
  * [{id: 1, value: 10}, {id: 2, value: 20}],
7883
7877
  * 'value',
7884
- * ); // => 20
7878
+ * ); // => [{id: 2, value: 20}]
7885
7879
  *
7886
- * max([], 'value'); // => Number.NaN
7880
+ * max([], 'value'); // => []
7887
7881
  * ```
7888
7882
  *
7889
7883
  * @param items List of items
7890
7884
  * @param key Key to use for value
7891
- * @returns Maximum value, or `Number.NaN` if no maximum can be found
7885
+ * @param first Return only the first item with the maximum value
7886
+ * @returns Item with the maximum value, or `undefined` if no maximum can be found
7887
+ */
7888
+ declare function max<Item extends PlainObject, ItemKey extends keyof NumericalValues<Item>>(items: Item[], key: ItemKey, first: true): Item | undefined;
7889
+ /**
7890
+ * Get the maximum value from a list of items
7891
+ *
7892
+ * @example
7893
+ * ```typescript
7894
+ * max(
7895
+ * [{id: 1, value: 10}, {id: 2, value: 20}],
7896
+ * item => item.value,
7897
+ * ); // => [{id: 2, value: 20}]
7898
+ *
7899
+ * max([], item => item.value); // => []
7900
+ * ```
7901
+ *
7902
+ * @param items List of items
7903
+ * @param callback Callback to get an item's value
7904
+ * @returns Items with the maximum value
7892
7905
  */
7893
- declare function max<Item extends PlainObject, ItemKey extends keyof NumericalValues<Item>>(items: Item[], key: ItemKey): number;
7906
+ declare function max<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): Item[];
7907
+ /**
7908
+ * Get the maximum value from a list of items
7909
+ *
7910
+ * @example
7911
+ * ```typescript
7912
+ * max(
7913
+ * [{id: 1, value: 10}, {id: 2, value: 20}],
7914
+ * 'value',
7915
+ * ); // => [{id: 2, value: 20}]
7916
+ *
7917
+ * max([], 'value'); // => []
7918
+ * ```
7919
+ *
7920
+ * @param items List of items
7921
+ * @param key Key to use for value
7922
+ * @returns Items with the maximum value
7923
+ */
7924
+ declare function max<Item extends PlainObject, ItemKey extends keyof NumericalValues<Item>>(items: Item[], key: ItemKey): Item[];
7894
7925
  /**
7895
7926
  * Get the maximum value from a list of numbers
7896
7927
  *
@@ -8008,17 +8039,35 @@ declare function median(array: number[]): number;
8008
8039
  *
8009
8040
  * @param items List of items
8010
8041
  * @param callback Callback to get an item's value
8011
- * @returns Minimum value, or `Number.NaN` if no minimum can be found
8042
+ * @param first Return only the first item with the minimum value
8043
+ * @returns Items with the minimum value
8012
8044
  */
8013
- declare function min<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): number;
8045
+ declare function min<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number, first: true): Item[];
8014
8046
  /**
8015
8047
  * Get the minimum value from a list of items
8016
8048
  *
8017
8049
  * @param items List of items
8018
8050
  * @param key Key to use for value
8019
- * @returns Minimum value, or `Number.NaN` if no minimum can be found
8051
+ * @param first Return only the first item with the minimum value
8052
+ * @returns Items with the minimum value
8053
+ */
8054
+ declare function min<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>, first: true): Item[];
8055
+ /**
8056
+ * Get the minimum value from a list of items
8057
+ *
8058
+ * @param items List of items
8059
+ * @param callback Callback to get an item's value
8060
+ * @returns Items with the minimum value
8061
+ */
8062
+ declare function min<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): Item[];
8063
+ /**
8064
+ * Get the minimum value from a list of items
8065
+ *
8066
+ * @param items List of items
8067
+ * @param key Key to use for value
8068
+ * @returns Items with the minimum value
8020
8069
  */
8021
- declare function min<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>): number;
8070
+ declare function min<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>): Item[];
8022
8071
  /**
8023
8072
  * Get the minimum value from a list of numbers
8024
8073
  *
@@ -8468,4 +8517,4 @@ declare class SizedSet<Value = unknown> extends Set<Value> {
8468
8517
  get(value: Value, update?: boolean): Value | undefined;
8469
8518
  }
8470
8519
  //#endregion
8471
- export { AnyResult, ArrayComparison, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArraySorter, ArraySorters, ArrayValueSorter, AssertProperty, Asserter, AssignOptions, Assigner, AsyncCancelableCallback, AttemptFlow, AttemptFlowPromise, Beacon, BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, type ColorType, type ColorTypeExtended, type ColorValue, type ColorValueExtended, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, EventPosition, ExtendedErr, ExtendedResult, Flow, FlowPromise, Frozen, FulfilledPromise, Fuzzy, FuzzyConfiguration, FuzzyOptions, FuzzyResult, FuzzySearchOptions, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, type HWBAColor, type HWBColor, Key$1 as Key, KeyedQueue, KeyedValue, Logger, Memoized, MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NormalizeOptions, Normalizer, NumericalKeys, NumericalValues, Observable, Ok, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, Queue, QueueError, QueueOptions, Queued, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, type Shaken, Simplify, SizedMap, SizedSet, type Smushed, SortDirection, Sorter, type Subscription, TemplateOptions, type TimedLogger, ToString, Transformer, TypedArray, UnionToIntersection, type Unsmushed, Unsubscriber, UnwrapValue, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
8520
+ export { AnyResult, ArrayComparison, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArraySorter, ArraySorters, ArrayValueSorter, AssertProperty, Asserter, AssignOptions, Assigner, AsyncCancelableCallback, AttemptFlow, AttemptFlowPromise, Beacon, BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, type ColorType, type ColorTypeExtended, type ColorValue, type ColorValueExtended, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, ExtendedErr, ExtendedResult, Flow, FlowPromise, Frozen, FulfilledPromise, Fuzzy, FuzzyConfiguration, FuzzyOptions, FuzzyResult, FuzzySearchOptions, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, type HWBAColor, type HWBColor, Key$1 as Key, KeyedQueue, KeyedValue, Logger, Memoized, MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NormalizeOptions, Normalizer, NumericalKeys, NumericalValues, Observable, Ok, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, Queue, QueueError, QueueOptions, Queued, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, type Shaken, Simplify, SizedMap, SizedSet, type Smushed, SortDirection, Sorter, type Subscription, TemplateOptions, type TimedLogger, ToString, Transformer, TypedArray, UnionToIntersection, type Unsmushed, Unsubscriber, UnwrapValue, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
package/dist/index.mjs CHANGED
@@ -881,49 +881,70 @@ function moveToIndex(array, value, index, key) {
881
881
  }
882
882
  //#endregion
883
883
  //#region src/internal/math/aggregate.ts
884
- function aggregate(type, array, key) {
884
+ function aggregate(type, array, key, first) {
885
885
  const length = Array.isArray(array) ? array.length : 0;
886
- if (length === 0) return {
886
+ const aggregation = {
887
+ array: false,
887
888
  count: 0,
889
+ first: first === true,
888
890
  value: NaN
889
891
  };
892
+ if (length === 0) return aggregation;
890
893
  const aggregator = aggregators[type];
891
894
  const callback = getAggregateCallback(key);
892
- let counted = 0;
893
- let aggregated = NaN;
895
+ aggregation.array = callback != null && (type === "max" || type === "min");
894
896
  let notNumber = true;
895
897
  for (let index = 0; index < length; index += 1) {
896
898
  const item = array[index];
897
899
  const value = callback == null ? item : callback(item, index, array);
898
900
  if (isNonNumber(value)) continue;
899
- aggregated = aggregator(aggregated, value, notNumber);
900
- counted += 1;
901
+ aggregation.value = aggregator(aggregation, value, notNumber, item);
902
+ aggregation.count += 1;
901
903
  notNumber = false;
902
904
  }
903
- return {
904
- count: counted,
905
- value: aggregated
906
- };
905
+ return aggregation;
906
+ }
907
+ function calculateSum(aggregation, value, notNumber) {
908
+ return notNumber ? value : aggregation.value + value;
909
+ }
910
+ function getAbsoluteValue(condition, aggregation, value, notNumber, item) {
911
+ if (notNumber || condition(aggregation, value)) {
912
+ if (aggregation.array) {
913
+ aggregation.items ??= {};
914
+ aggregation.items[value] ??= [];
915
+ aggregation.items[value].push(item);
916
+ }
917
+ return value;
918
+ }
919
+ return aggregation.value;
907
920
  }
908
921
  function getAggregateCallback(key) {
909
922
  if (key == null) return;
910
923
  return typeof key === "function" ? key : (item) => item[key];
911
924
  }
912
- function max(array, key) {
913
- return getAggregated("max", array, key);
925
+ function getAggregated(type, array, key, first) {
926
+ const aggregation = aggregate(type, array, key, first);
927
+ if (aggregation.count === 0) return aggregation.array ? aggregation.first ? void 0 : [] : NaN;
928
+ if (aggregation.array) {
929
+ const array = aggregation.items[aggregation.value];
930
+ return aggregation.first ? array[0] : array;
931
+ }
932
+ return aggregation.value;
933
+ }
934
+ function isMaxValue(aggregation, value) {
935
+ return aggregation.array ? value >= aggregation.value : value > aggregation.value;
914
936
  }
915
- function calculateSum(current, value, notNumber) {
916
- return notNumber ? value : current + value;
937
+ function isMinValue(aggregation, value) {
938
+ return aggregation.array ? value <= aggregation.value : value < aggregation.value;
917
939
  }
918
- function getAggregated(type, array, key) {
919
- const aggregated = aggregate(type, array, key);
920
- return aggregated.count > 0 ? aggregated.value : NaN;
940
+ function max(array, key, first) {
941
+ return getAggregated("max", array, key, first);
921
942
  }
922
943
  const AGGREGATION_AVERAGE = "average";
923
944
  const aggregators = {
924
945
  average: calculateSum,
925
- max: (current, value, notNumber) => notNumber || value > current ? value : current,
926
- min: (current, value, notNumber) => notNumber || value < current ? value : current,
946
+ max: getAbsoluteValue.bind(void 0, isMaxValue),
947
+ min: getAbsoluteValue.bind(void 0, isMinValue),
927
948
  sum: calculateSum
928
949
  };
929
950
  //#endregion
@@ -5753,8 +5774,8 @@ function median(array, key) {
5753
5774
  }
5754
5775
  return numbers[Math.floor(length / 2)];
5755
5776
  }
5756
- function min(array, key) {
5757
- return getAggregated("min", array, key);
5777
+ function min(array, key, first) {
5778
+ return getAggregated("min", array, key, first);
5758
5779
  }
5759
5780
  function sum(array, key) {
5760
5781
  return getAggregated("sum", array, key);
@@ -1,13 +1,17 @@
1
1
  import { NumericalValues, PlainObject } from "../../models.mjs";
2
2
  //#region src/internal/math/aggregate.d.ts
3
3
  type Aggregation = {
4
+ array: boolean;
4
5
  count: number;
6
+ first: boolean;
7
+ items?: Record<number, unknown[]>;
5
8
  value: number;
6
9
  };
7
10
  type AggregationType = 'average' | 'max' | 'min' | 'sum';
8
11
  type NonAverageAggregationType = 'max' | 'min' | 'sum';
9
- declare function aggregate(type: AggregationType, array: unknown[], key: unknown): Aggregation;
12
+ declare function aggregate(type: AggregationType, array: unknown[], key: unknown, first?: unknown): Aggregation;
10
13
  declare function getAggregateCallback(key: unknown): Function | undefined;
14
+ declare function getAggregated(type: NonAverageAggregationType, array: unknown[], key?: unknown, first?: unknown): unknown;
11
15
  /**
12
16
  * Get the maximum value from a list of items
13
17
  *
@@ -16,16 +20,17 @@ declare function getAggregateCallback(key: unknown): Function | undefined;
16
20
  * max(
17
21
  * [{id: 1, value: 10}, {id: 2, value: 20}],
18
22
  * item => item.value,
19
- * ); // => 20
23
+ * ); // => [{id: 2, value: 20}]
20
24
  *
21
- * max([], item => item.value); // => Number.NaN
25
+ * max([], item => item.value); // => []
22
26
  * ```
23
27
  *
24
28
  * @param items List of items
25
29
  * @param callback Callback to get an item's value
26
- * @returns Maximum value, or `Number.NaN` if no maximum can be found
30
+ * @param first Return only the first item with the maximum value
31
+ * @returns Item with the maximum value, or `undefined` if no maximum can be found
27
32
  */
28
- declare function max<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): number;
33
+ declare function max<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number, first: true): Item | undefined;
29
34
  /**
30
35
  * Get the maximum value from a list of items
31
36
  *
@@ -34,16 +39,53 @@ declare function max<Item>(items: Item[], callback: (item: Item, index: number,
34
39
  * max(
35
40
  * [{id: 1, value: 10}, {id: 2, value: 20}],
36
41
  * 'value',
37
- * ); // => 20
42
+ * ); // => [{id: 2, value: 20}]
38
43
  *
39
- * max([], 'value'); // => Number.NaN
44
+ * max([], 'value'); // => []
40
45
  * ```
41
46
  *
42
47
  * @param items List of items
43
48
  * @param key Key to use for value
44
- * @returns Maximum value, or `Number.NaN` if no maximum can be found
49
+ * @param first Return only the first item with the maximum value
50
+ * @returns Item with the maximum value, or `undefined` if no maximum can be found
51
+ */
52
+ declare function max<Item extends PlainObject, ItemKey extends keyof NumericalValues<Item>>(items: Item[], key: ItemKey, first: true): Item | undefined;
53
+ /**
54
+ * Get the maximum value from a list of items
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * max(
59
+ * [{id: 1, value: 10}, {id: 2, value: 20}],
60
+ * item => item.value,
61
+ * ); // => [{id: 2, value: 20}]
62
+ *
63
+ * max([], item => item.value); // => []
64
+ * ```
65
+ *
66
+ * @param items List of items
67
+ * @param callback Callback to get an item's value
68
+ * @returns Items with the maximum value
69
+ */
70
+ declare function max<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): Item[];
71
+ /**
72
+ * Get the maximum value from a list of items
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * max(
77
+ * [{id: 1, value: 10}, {id: 2, value: 20}],
78
+ * 'value',
79
+ * ); // => [{id: 2, value: 20}]
80
+ *
81
+ * max([], 'value'); // => []
82
+ * ```
83
+ *
84
+ * @param items List of items
85
+ * @param key Key to use for value
86
+ * @returns Items with the maximum value
45
87
  */
46
- declare function max<Item extends PlainObject, ItemKey extends keyof NumericalValues<Item>>(items: Item[], key: ItemKey): number;
88
+ declare function max<Item extends PlainObject, ItemKey extends keyof NumericalValues<Item>>(items: Item[], key: ItemKey): Item[];
47
89
  /**
48
90
  * Get the maximum value from a list of numbers
49
91
  *
@@ -57,7 +99,6 @@ declare function max<Item extends PlainObject, ItemKey extends keyof NumericalVa
57
99
  * @returns Maximum value, or `Number.NaN` if no maximum can be found
58
100
  */
59
101
  declare function max(values: number[]): number;
60
- declare function getAggregated(type: NonAverageAggregationType, array: unknown[], key?: unknown): number;
61
102
  declare const AGGREGATION_AVERAGE: AggregationType;
62
103
  declare const AGGREGATION_MAX = "max";
63
104
  declare const AGGREGATION_MIN = "min";
@@ -1,42 +1,63 @@
1
1
  import { isNonNumber } from "../is.mjs";
2
2
  //#region src/internal/math/aggregate.ts
3
- function aggregate(type, array, key) {
3
+ function aggregate(type, array, key, first) {
4
4
  const length = Array.isArray(array) ? array.length : 0;
5
- if (length === 0) return {
5
+ const aggregation = {
6
+ array: false,
6
7
  count: 0,
8
+ first: first === true,
7
9
  value: NaN
8
10
  };
11
+ if (length === 0) return aggregation;
9
12
  const aggregator = aggregators[type];
10
13
  const callback = getAggregateCallback(key);
11
- let counted = 0;
12
- let aggregated = NaN;
14
+ aggregation.array = callback != null && (type === "max" || type === "min");
13
15
  let notNumber = true;
14
16
  for (let index = 0; index < length; index += 1) {
15
17
  const item = array[index];
16
18
  const value = callback == null ? item : callback(item, index, array);
17
19
  if (isNonNumber(value)) continue;
18
- aggregated = aggregator(aggregated, value, notNumber);
19
- counted += 1;
20
+ aggregation.value = aggregator(aggregation, value, notNumber, item);
21
+ aggregation.count += 1;
20
22
  notNumber = false;
21
23
  }
22
- return {
23
- count: counted,
24
- value: aggregated
25
- };
24
+ return aggregation;
25
+ }
26
+ function calculateSum(aggregation, value, notNumber) {
27
+ return notNumber ? value : aggregation.value + value;
28
+ }
29
+ function getAbsoluteValue(condition, aggregation, value, notNumber, item) {
30
+ if (notNumber || condition(aggregation, value)) {
31
+ if (aggregation.array) {
32
+ aggregation.items ??= {};
33
+ aggregation.items[value] ??= [];
34
+ aggregation.items[value].push(item);
35
+ }
36
+ return value;
37
+ }
38
+ return aggregation.value;
26
39
  }
27
40
  function getAggregateCallback(key) {
28
41
  if (key == null) return;
29
42
  return typeof key === "function" ? key : (item) => item[key];
30
43
  }
31
- function max(array, key) {
32
- return getAggregated("max", array, key);
44
+ function getAggregated(type, array, key, first) {
45
+ const aggregation = aggregate(type, array, key, first);
46
+ if (aggregation.count === 0) return aggregation.array ? aggregation.first ? void 0 : [] : NaN;
47
+ if (aggregation.array) {
48
+ const array = aggregation.items[aggregation.value];
49
+ return aggregation.first ? array[0] : array;
50
+ }
51
+ return aggregation.value;
52
+ }
53
+ function isMaxValue(aggregation, value) {
54
+ return aggregation.array ? value >= aggregation.value : value > aggregation.value;
33
55
  }
34
- function calculateSum(current, value, notNumber) {
35
- return notNumber ? value : current + value;
56
+ function isMinValue(aggregation, value) {
57
+ return aggregation.array ? value <= aggregation.value : value < aggregation.value;
36
58
  }
37
- function getAggregated(type, array, key) {
38
- const aggregated = aggregate(type, array, key);
39
- return aggregated.count > 0 ? aggregated.value : NaN;
59
+ function max(array, key, first) {
60
+ return getAggregated("max", array, key, first);
40
61
  }
41
62
  const AGGREGATION_AVERAGE = "average";
42
63
  const AGGREGATION_MAX = "max";
@@ -44,8 +65,8 @@ const AGGREGATION_MIN = "min";
44
65
  const AGGREGATION_SUM = "sum";
45
66
  const aggregators = {
46
67
  average: calculateSum,
47
- max: (current, value, notNumber) => notNumber || value > current ? value : current,
48
- min: (current, value, notNumber) => notNumber || value < current ? value : current,
68
+ max: getAbsoluteValue.bind(void 0, isMaxValue),
69
+ min: getAbsoluteValue.bind(void 0, isMinValue),
49
70
  sum: calculateSum
50
71
  };
51
72
  //#endregion
package/dist/math.d.mts CHANGED
@@ -94,17 +94,35 @@ declare function median(array: number[]): number;
94
94
  *
95
95
  * @param items List of items
96
96
  * @param callback Callback to get an item's value
97
- * @returns Minimum value, or `Number.NaN` if no minimum can be found
97
+ * @param first Return only the first item with the minimum value
98
+ * @returns Items with the minimum value
98
99
  */
99
- declare function min<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): number;
100
+ declare function min<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number, first: true): Item[];
100
101
  /**
101
102
  * Get the minimum value from a list of items
102
103
  *
103
104
  * @param items List of items
104
105
  * @param key Key to use for value
105
- * @returns Minimum value, or `Number.NaN` if no minimum can be found
106
+ * @param first Return only the first item with the minimum value
107
+ * @returns Items with the minimum value
108
+ */
109
+ declare function min<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>, first: true): Item[];
110
+ /**
111
+ * Get the minimum value from a list of items
112
+ *
113
+ * @param items List of items
114
+ * @param callback Callback to get an item's value
115
+ * @returns Items with the minimum value
116
+ */
117
+ declare function min<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): Item[];
118
+ /**
119
+ * Get the minimum value from a list of items
120
+ *
121
+ * @param items List of items
122
+ * @param key Key to use for value
123
+ * @returns Items with the minimum value
106
124
  */
107
- declare function min<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>): number;
125
+ declare function min<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>): Item[];
108
126
  /**
109
127
  * Get the minimum value from a list of numbers
110
128
  *
package/dist/math.mjs CHANGED
@@ -54,8 +54,8 @@ function median(array, key) {
54
54
  }
55
55
  return numbers[Math.floor(length / 2)];
56
56
  }
57
- function min(array, key) {
58
- return getAggregated("min", array, key);
57
+ function min(array, key, first) {
58
+ return getAggregated("min", array, key, first);
59
59
  }
60
60
  function sum(array, key) {
61
61
  return getAggregated("sum", array, key);
package/dist/models.d.mts CHANGED
@@ -31,13 +31,6 @@ type CancelableCallback<Callback extends GenericCallback> = Callback & {
31
31
  * A generic class constructor
32
32
  */
33
33
  type Constructor<Instance = unknown> = new (...args: any[]) => Instance;
34
- /**
35
- * Position of an event
36
- */
37
- type EventPosition = {
38
- x: number;
39
- y: number;
40
- };
41
34
  /**
42
35
  * A generic async callback function
43
36
  */
@@ -161,4 +154,4 @@ type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Un
161
154
  */
162
155
  type Unsubscriber = () => void;
163
156
  //#endregion
164
- export { ArrayOrPlainObject, AsyncCancelableCallback, BuiltIns, CancelableCallback, Constructor, EventPosition, GenericAsyncCallback, GenericCallback, Key, KeyedValue, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, RequiredKeys, Simplify, ToString, TypedArray, UnionToIntersection, Unsubscriber };
157
+ export { ArrayOrPlainObject, AsyncCancelableCallback, BuiltIns, CancelableCallback, Constructor, GenericAsyncCallback, GenericCallback, Key, KeyedValue, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, RequiredKeys, Simplify, ToString, TypedArray, UnionToIntersection, Unsubscriber };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/atoms",
3
- "version": "0.195.1",
3
+ "version": "0.196.0",
4
4
  "description": "Atomic utilities for making your JavaScript better.",
5
5
  "keywords": [
6
6
  "array",