Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions collections/max_by.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,41 @@ export function maxBy<T>(
| ((el: T) => bigint)
| ((el: T) => Date),
): T | undefined {
let max: T | undefined;
let maxValue: ReturnType<typeof selector> | undefined;
if (Array.isArray(array)) {
const length = array.length;
if (length === 0) return undefined;

for (const current of array) {
const currentValue = selector(current);
let max: T = array[0]!;
let maxValue = selector(max);

if (maxValue === undefined || currentValue > maxValue) {
max = current;
for (let i = 1; i < length; i++) {
const current = array[i]!;
const currentValue = selector(current);
if (currentValue > maxValue) {
max = current;
maxValue = currentValue;
}
}

return max;
}

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

if (first.done) return undefined;

let max: T = first.value;
let maxValue = selector(max);

let next = iter.next();
while (!next.done) {
const currentValue = selector(next.value);
if (currentValue > maxValue) {
max = next.value;
maxValue = currentValue;
}
next = iter.next();
}

return max;
Expand Down
67 changes: 61 additions & 6 deletions collections/max_by_test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2025 the Deno authors. MIT license.

import { assertEquals } from "@std/assert";
import { assertEquals, assertStrictEquals } from "@std/assert";
import { maxBy } from "./max_by.ts";

Deno.test("maxBy() handles array input", () => {
Expand Down Expand Up @@ -40,6 +40,10 @@ Deno.test("maxBy() handles array input with multiple max", () => {
assertEquals(max, { name: "John", age: 42 });
});

Deno.test("maxBy() handles single element array", () => {
assertEquals(maxBy([42], (i) => i), 42);
});

Deno.test("maxBy() handles array of positive numbers", () => {
const input = [2, 3, 5];

Expand Down Expand Up @@ -72,6 +76,18 @@ Deno.test("maxBy() handles of empty array", () => {
assertEquals(max, undefined);
});

Deno.test("maxBy() handles empty input", () => {
const emptyArray: Array<{ age: number }> = [];
const max = maxBy(emptyArray, (it) => it.age);

assertEquals(max, undefined);
});

Deno.test("maxBy() handles empty generator", () => {
function* gen(): Generator<number> {}
assertEquals(maxBy(gen(), (i) => i), undefined);
});

Deno.test("maxBy() handles array of numbers with multiple max", () => {
const input = [2, 3, 5, 5];

Expand All @@ -96,6 +112,12 @@ Deno.test("maxBy() handles array of numbers with NaN", () => {
assertEquals(max, 5);
});

Deno.test("maxBy() handles NaN at first position", () => {
const input = [NaN, 2, 3];
const max = maxBy(input, (i) => i);
assertEquals(max, NaN);
});

Deno.test("maxBy() handles no mutation", () => {
const input = [2, 3, 5];

Expand All @@ -104,11 +126,11 @@ Deno.test("maxBy() handles no mutation", () => {
assertEquals(input, [2, 3, 5]);
});

Deno.test("maxBy() handles empty input", () => {
const emptyArray: Array<{ age: number }> = [];
const max = maxBy(emptyArray, (it) => it.age);

assertEquals(max, undefined);
Deno.test("maxBy() returns same object reference", () => {
const john = { name: "John", age: 42 };
const input = [{ name: "Kyle", age: 34 }, john, { name: "Anna", age: 23 }];
const max = maxBy(input, (i) => i.age);
assertStrictEquals(max, john);
});

Deno.test({
Expand Down Expand Up @@ -136,3 +158,36 @@ Deno.test({
assertEquals(maxBy(input, (it) => new Date(it)), "February 1, 2022");
},
});

Deno.test("maxBy() handles generator input", () => {
function* gen() {
yield { name: "Kyle", age: 34 };
yield { name: "John", age: 42 };
yield { name: "Anna", age: 23 };
}
const max = maxBy(gen(), (i) => i.age);
assertEquals(max, { name: "John", age: 42 });
});

Deno.test("maxBy() handles single element generator", () => {
function* gen() {
yield 42;
}
assertEquals(maxBy(gen(), (i) => i), 42);
});

Deno.test("maxBy() handles Set input", () => {
const input = new Set([5, 2, 8, 1, 9]);
const max = maxBy(input, (i) => i);
assertEquals(max, 9);
});

Deno.test("maxBy() handles Map values", () => {
const input = new Map([
["a", { age: 34 }],
["b", { age: 23 }],
["c", { age: 45 }],
]);
const max = maxBy(input.values(), (i) => i.age);
assertEquals(max, { age: 45 });
});
37 changes: 31 additions & 6 deletions collections/min_by.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,41 @@ export function minBy<T>(
| ((el: T) => bigint)
| ((el: T) => Date),
): T | undefined {
let min: T | undefined;
let minValue: ReturnType<typeof selector> | undefined;
if (Array.isArray(array)) {
const length = array.length;
if (length === 0) return undefined;

for (const current of array) {
const currentValue = selector(current);
let min: T = array[0]!;
let minValue = selector(min);

if (minValue === undefined || currentValue < minValue) {
min = current;
for (let i = 1; i < length; i++) {
const current = array[i]!;
const currentValue = selector(current);
if (currentValue < minValue) {
min = current;
minValue = currentValue;
}
}

return min;
}

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

if (first.done) return undefined;

let min: T = first.value;
let minValue = selector(min);

let next = iter.next();
while (!next.done) {
const currentValue = selector(next.value);
if (currentValue < minValue) {
min = next.value;
minValue = currentValue;
}
next = iter.next();
}

return min;
Expand Down
67 changes: 61 additions & 6 deletions collections/min_by_test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2018-2025 the Deno authors. MIT license.

import { assertEquals } from "@std/assert";
import { assertEquals, assertStrictEquals } from "@std/assert";
import { minBy } from "./min_by.ts";

Deno.test("minBy() handles array input", () => {
Expand Down Expand Up @@ -40,6 +40,10 @@ Deno.test("minBy() handles array input with multiple min", () => {
assertEquals(min, { name: "Anna", age: 23 });
});

Deno.test("minBy() handles single element array", () => {
assertEquals(minBy([42], (i) => i), 42);
});

Deno.test("minBy() handles array of positive numbers", () => {
const input = [2, 3, 5];

Expand Down Expand Up @@ -72,6 +76,19 @@ Deno.test("minBy() handles of empty array", () => {
assertEquals(min, undefined);
});

Deno.test("minBy() handles empty input", () => {
const input: Array<{ age: number }> = [];

const min = minBy(input, (i) => i.age);

assertEquals(min, undefined);
});

Deno.test("minBy() handles empty generator", () => {
function* gen(): Generator<number> {}
assertEquals(minBy(gen(), (i) => i), undefined);
});

Deno.test("minBy() handles array of numbers with multiple min", () => {
const input = [2, 3, 5, 5];

Expand All @@ -96,6 +113,12 @@ Deno.test("minBy() handles array of numbers with NaN", () => {
assertEquals(min, 2);
});

Deno.test("minBy() handles NaN at first position", () => {
const input = [NaN, 2, 3];
const min = minBy(input, (i) => i);
assertEquals(min, NaN);
});

Deno.test("minBy() handles no mutation", () => {
const input = [2, 3, 5, NaN];

Expand All @@ -104,12 +127,11 @@ Deno.test("minBy() handles no mutation", () => {
assertEquals(input, [2, 3, 5, NaN]);
});

Deno.test("minBy() handles empty input", () => {
const input: Array<{ age: number }> = [];

Deno.test("minBy() returns same object reference", () => {
const anna = { name: "Anna", age: 23 };
const input = [{ name: "Kyle", age: 34 }, anna, { name: "John", age: 42 }];
const min = minBy(input, (i) => i.age);

assertEquals(min, undefined);
assertStrictEquals(min, anna);
});

Deno.test({
Expand Down Expand Up @@ -137,3 +159,36 @@ Deno.test({
assertEquals(minBy(input, (it) => new Date(it)), "December 17, 1995");
},
});

Deno.test("minBy() handles generator input", () => {
function* gen() {
yield { name: "Kyle", age: 34 };
yield { name: "John", age: 42 };
yield { name: "Anna", age: 23 };
}
const min = minBy(gen(), (i) => i.age);
assertEquals(min, { name: "Anna", age: 23 });
});

Deno.test("minBy() handles single element generator", () => {
function* gen() {
yield 42;
}
assertEquals(minBy(gen(), (i) => i), 42);
});

Deno.test("minBy() handles Set input", () => {
const input = new Set([5, 2, 8, 1, 9]);
const min = minBy(input, (i) => i);
assertEquals(min, 1);
});

Deno.test("minBy() handles Map values", () => {
const input = new Map([
["a", { age: 34 }],
["b", { age: 23 }],
["c", { age: 45 }],
]);
const min = minBy(input.values(), (i) => i.age);
assertEquals(min, { age: 23 });
});
Loading