All files / collections / unstable_max_of.ts

42.86% Branches 3/7
38.89% Lines 14/36
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x3
 
 
 
 
 
x3
x3
 
x6
x6
 
 
x6
 
 
x6
x13
x13
x19
 
 
 
x13
 
x6
x6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
x6

















































































I


I





I





I






















// Copyright 2018-2026 the Deno authors. MIT license.
// This module is browser compatible.

/**
 * Applies the given selector to all elements of the provided collection and
 * returns the max value of all elements. If an empty array is provided the
 * function will return undefined.
 *
 * @experimental **UNSTABLE**: New API, yet to be vetted.
 *
 * @typeParam T The type of the elements in the array.
 *
 * @param array The array to find the maximum element in.
 * @param selector The function to get the value to compare from each element.
 *
 * @returns The largest value of the given function or undefined if there are no
 * elements.
 *
 * @example Basic usage
 * ```ts
 * import { maxOf } from "@std/collections/unstable-max-of";
 * import { assertEquals } from "@std/assert";
 *
 * const inventory = [
 *   { name: "mustard", count: 2 },
 *   { name: "soy", count: 4 },
 *   { name: "tomato", count: 32 },
 * ];
 *
 * const maxCount = maxOf(inventory, (item) => item.count);
 *
 * assertEquals(maxCount, 32);
 * ```
 */
export function maxOf<T>(
  array: Iterable<T>,
  selector: (el: T, index: number) => number,
): number | undefined;
/**
 * Applies the given selector to all elements of the provided collection and
 * returns the max value of all elements. If an empty array is provided the
 * function will return undefined.
 *
 * @typeParam T The type of the elements in the array.
 *
 * @param array The array to find the maximum element in.
 * @param selector The function to get the value to compare from each element.
 *
 * @returns The first element that is the largest value of the given function or
 * undefined if there are no elements.
 *
 * @example Basic usage
 * ```ts
 * import { maxOf } from "@std/collections/unstable-max-of";
 * import { assertEquals } from "@std/assert";
 *
 * const inventory = [
 *   { name: "mustard", count: 2n },
 *   { name: "soy", count: 4n },
 *   { name: "tomato", count: 32n },
 * ];
 *
 * const maxCount = maxOf(inventory, (i) => i.count);
 *
 * assertEquals(maxCount, 32n);
 * ```
 */
export function maxOf<T>(
  array: Iterable<T>,
  selector: (el: T, index: number) => bigint,
): bigint | undefined;
export function maxOf<
  T,
  S extends
    | ((el: T, index: number) => number)
    | ((el: T, index: number) => bigint),
>(
  array: Iterable<T>,
  selector: S,
): ReturnType<S> | undefined {
  if (Array.isArray(array)) {
    const length = array.length;
    if (length === 0) return undefined;

    let max = selector(array[0]!, 0) as ReturnType<S>;
    if (Number.isNaN(max)) return max;

    for (let i = 1; i < length; i++) {
      const currentValue = selector(array[i]!, i) as ReturnType<S>;
      if (currentValue > max) {
        max = currentValue;
      } else if (Number.isNaN(currentValue)) {
        return currentValue;
      }
    }

    return max;
  }

  let index = 0;
  const iter = array[Symbol.iterator]();
  const first = iter.next();

  if (first.done) return undefined;

  let max = selector(first.value, index++) as ReturnType<S>;
  if (Number.isNaN(max)) return max;

  let next = iter.next();
  while (!next.done) {
    const currentValue = selector(next.value, index++) as ReturnType<S>;
    if (currentValue > max) {
      max = currentValue;
    } else if (Number.isNaN(currentValue)) {
      return currentValue;
    }
    next = iter.next();
  }

  return max;
}