From 65c0d658c1c93b08572fd0ce3fc0bba899a2ce05 Mon Sep 17 00:00:00 2001 From: Caleb Cox Date: Tue, 4 Feb 2025 20:07:28 -0600 Subject: [PATCH] feat: add index arg to collection methods Closes #6288 --- collections/distinct_by.ts | 5 +++-- collections/distinct_by_test.ts | 13 ++++++++++++- collections/drop_last_while.ts | 4 ++-- collections/drop_last_while_test.ts | 8 ++++++++ collections/drop_while.ts | 4 ++-- collections/drop_while_test.ts | 8 ++++++++ collections/find_single.ts | 5 +++-- collections/find_single_test.ts | 12 +++++++++++- collections/first_not_nullish_of.ts | 5 +++-- collections/first_not_nullish_of_test.ts | 12 +++++++++++- collections/join_to_string.ts | 4 ++-- collections/join_to_string_test.ts | 11 +++++++++++ collections/map_not_nullish.ts | 5 +++-- collections/map_not_nullish_test.ts | 15 ++++++++++++++- collections/max_by.ts | 19 ++++++++++--------- collections/max_by_test.ts | 11 +++++++++++ collections/max_of.ts | 14 ++++++++++---- collections/max_of_test.ts | 11 +++++++++++ collections/min_by.ts | 19 ++++++++++--------- collections/min_by_test.ts | 11 +++++++++++ collections/min_of.ts | 14 ++++++++++---- collections/min_of_test.ts | 11 +++++++++++ collections/partition.ts | 9 +++++---- collections/partition_test.ts | 12 +++++++++++- collections/sort_by.ts | 18 +++++++++--------- collections/sort_by_test.ts | 7 +++++++ collections/sum_of.ts | 5 +++-- collections/sum_of_test.ts | 8 ++++++++ collections/take_last_while.ts | 4 ++-- collections/take_last_while_test.ts | 8 ++++++++ collections/take_while.ts | 4 ++-- collections/take_while_test.ts | 8 ++++++++ 32 files changed, 240 insertions(+), 64 deletions(-) diff --git a/collections/distinct_by.ts b/collections/distinct_by.ts index 94482cc0e3ce..f4bac2143550 100644 --- a/collections/distinct_by.ts +++ b/collections/distinct_by.ts @@ -29,12 +29,13 @@ */ export function distinctBy( array: Iterable, - discriminator: (el: T) => D, + discriminator: (el: T, index: number) => D, ): T[] { const keys = new Set(); const result: T[] = []; + let index = 0; for (const element of array) { - const key = discriminator(element); + const key = discriminator(element, index++); if (!keys.has(key)) { keys.add(key); result.push(element); diff --git a/collections/distinct_by_test.ts b/collections/distinct_by_test.ts index 8fc4d8568bfd..bc9d62761872 100644 --- a/collections/distinct_by_test.ts +++ b/collections/distinct_by_test.ts @@ -5,7 +5,7 @@ import { distinctBy } from "./distinct_by.ts"; function distinctByTest( array: Array, - selector: (element: I) => unknown, + selector: (element: I, index: number) => unknown, expected: Array, message?: string, ) { @@ -117,3 +117,14 @@ Deno.test({ ); }, }); + +Deno.test({ + name: "distinctBy() passes index to selector", + fn() { + distinctByTest( + [25, "asdf", true], + (_, index) => index > 1, + [25, true], + ); + }, +}); diff --git a/collections/drop_last_while.ts b/collections/drop_last_while.ts index 9555c9cc36a3..27e0ce93a314 100644 --- a/collections/drop_last_while.ts +++ b/collections/drop_last_while.ts @@ -27,10 +27,10 @@ */ export function dropLastWhile( array: readonly T[], - predicate: (el: T) => boolean, + predicate: (el: T, index: number) => boolean, ): T[] { let offset = array.length; - while (0 < offset && predicate(array[offset - 1] as T)) offset--; + while (0 < offset && predicate(array[offset - 1] as T, offset - 1)) offset--; return array.slice(0, offset); } diff --git a/collections/drop_last_while_test.ts b/collections/drop_last_while_test.ts index f42a89077136..f44dd278eee4 100644 --- a/collections/drop_last_while_test.ts +++ b/collections/drop_last_while_test.ts @@ -50,3 +50,11 @@ Deno.test("dropLastWhile() returns empty array when all elements get dropped", ( assertEquals(actual, []); }); + +Deno.test("dropLastWhile() passes index to predicate", () => { + const array = [20, 30, 20]; + + const actual = dropLastWhile(array, (_, index) => index > 1); + + assertEquals(actual, [20, 30]); +}); diff --git a/collections/drop_while.ts b/collections/drop_while.ts index 18703c1604a3..1ffbca0a2de9 100644 --- a/collections/drop_while.ts +++ b/collections/drop_while.ts @@ -26,12 +26,12 @@ */ export function dropWhile( array: readonly T[], - predicate: (el: T) => boolean, + predicate: (el: T, index: number) => boolean, ): T[] { let offset = 0; const length = array.length; - while (length > offset && predicate(array[offset] as T)) { + while (length > offset && predicate(array[offset] as T, offset)) { offset++; } diff --git a/collections/drop_while_test.ts b/collections/drop_while_test.ts index 8227adcc9a81..bcd13f553632 100644 --- a/collections/drop_while_test.ts +++ b/collections/drop_while_test.ts @@ -55,3 +55,11 @@ Deno.test("dropWhile() returns the same array when all elements match the predic assertEquals(actual, []); }); + +Deno.test("dropWhile() passes index to predicate", () => { + const array = [20, 30, 20]; + + const actual = dropWhile(array, (_, index) => index < 1); + + assertEquals(actual, [30, 20]); +}); diff --git a/collections/find_single.ts b/collections/find_single.ts index d9e94dd3af18..ce2ecf551783 100644 --- a/collections/find_single.ts +++ b/collections/find_single.ts @@ -32,12 +32,13 @@ */ export function findSingle( array: Iterable, - predicate: (el: T) => boolean, + predicate: (el: T, index: number) => boolean, ): T | undefined { let match: T | undefined; let found = false; + let index = 0; for (const element of array) { - if (predicate(element)) { + if (predicate(element, index++)) { if (found) return undefined; found = true; match = element; diff --git a/collections/find_single_test.ts b/collections/find_single_test.ts index b627416b4ed3..642746e8ee35 100644 --- a/collections/find_single_test.ts +++ b/collections/find_single_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "@std/assert"; import { findSingle } from "./find_single.ts"; function findSingleTest( - input: [Array, (element: I) => boolean], + input: [Array, (element: I, index: number) => boolean], expected: I | undefined, message?: string, ) { @@ -103,3 +103,13 @@ Deno.test({ ); }, }); + +Deno.test({ + name: "findSingle() passes index to predicate", + fn() { + findSingleTest( + [[9, 12, 13], (_, index) => index === 1], + 12, + ); + }, +}); diff --git a/collections/first_not_nullish_of.ts b/collections/first_not_nullish_of.ts index 01cc329aba4f..f9fdd648ebfb 100644 --- a/collections/first_not_nullish_of.ts +++ b/collections/first_not_nullish_of.ts @@ -33,10 +33,11 @@ */ export function firstNotNullishOf( array: Iterable, - selector: (item: T) => O | undefined | null, + selector: (item: T, index: number) => O | undefined | null, ): NonNullable | undefined { + let index = 0; for (const current of array) { - const selected = selector(current); + const selected = selector(current, index++); if (selected !== null && selected !== undefined) { return selected as NonNullable; diff --git a/collections/first_not_nullish_of_test.ts b/collections/first_not_nullish_of_test.ts index 32fdf4fad4a1..bce5be238204 100644 --- a/collections/first_not_nullish_of_test.ts +++ b/collections/first_not_nullish_of_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "@std/assert"; import { firstNotNullishOf } from "./first_not_nullish_of.ts"; function firstNotNullishOfTest( - input: [Array, (el: T) => O | undefined | null], + input: [Array, (el: T, index: number) => O | undefined | null], expected: NonNullable | undefined, message?: string, ) { @@ -85,3 +85,13 @@ Deno.test({ ); }, }); + +Deno.test({ + name: "firstNotNullishOf() passes index to selector", + fn() { + firstNotNullishOfTest( + [[1, 2, 3, 4], (it, index) => index < 1 ? null : it], + 2, + ); + }, +}); diff --git a/collections/join_to_string.ts b/collections/join_to_string.ts index e5e3b675bed6..10833681decc 100644 --- a/collections/join_to_string.ts +++ b/collections/join_to_string.ts @@ -77,7 +77,7 @@ export type JoinToStringOptions = { */ export function joinToString( array: Iterable, - selector: (el: T) => string, + selector: (el: T, index: number) => string, options: Readonly = {}, ): string { const { @@ -101,7 +101,7 @@ export function joinToString( break; } - result += selector(el); + result += selector(el, index); index++; } diff --git a/collections/join_to_string_test.ts b/collections/join_to_string_test.ts index 6ee12ac7d9dd..7fae6922a154 100644 --- a/collections/join_to_string_test.ts +++ b/collections/join_to_string_test.ts @@ -144,3 +144,14 @@ Deno.test({ assertEquals(out, "result: Kim and others are winners"); }, }); + +Deno.test({ + name: "joinToString() passes index to selector", + fn() { + const arr = ["Kim", "Anna", "Tim"]; + + const out = joinToString(arr, (it, index) => it + index); + + assertEquals(out, "Kim0,Anna1,Tim2"); + }, +}); diff --git a/collections/map_not_nullish.ts b/collections/map_not_nullish.ts index 0ffa87994410..26d775429dea 100644 --- a/collections/map_not_nullish.ts +++ b/collections/map_not_nullish.ts @@ -33,12 +33,13 @@ */ export function mapNotNullish( array: Iterable, - transformer: (el: T) => O, + transformer: (el: T, index: number) => O, ): NonNullable[] { const result: NonNullable[] = []; + let index = 0; for (const element of array) { - const transformedElement = transformer(element); + const transformedElement = transformer(element, index++); if (transformedElement !== undefined && transformedElement !== null) { result.push(transformedElement as NonNullable); diff --git a/collections/map_not_nullish_test.ts b/collections/map_not_nullish_test.ts index e6efbc4ae786..dabffa890315 100644 --- a/collections/map_not_nullish_test.ts +++ b/collections/map_not_nullish_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "@std/assert"; import { mapNotNullish } from "./map_not_nullish.ts"; function mapNotNullishTest( - input: [Array, (el: T) => O | undefined | null], + input: [Array, (el: T, index: number) => O | undefined | null], expected: Array, message?: string, ) { @@ -90,3 +90,16 @@ Deno.test({ ); }, }); + +Deno.test({ + name: "mapNotNullish() passes index to transformer", + fn() { + mapNotNullishTest( + [ + [1, 2, 3, 4], + (it, index) => index === 1 ? null : it + index, + ], + [1, 5, 7], + ); + }, +}); diff --git a/collections/max_by.ts b/collections/max_by.ts index 968875e2d824..899280f6feb8 100644 --- a/collections/max_by.ts +++ b/collections/max_by.ts @@ -31,7 +31,7 @@ */ export function maxBy( array: Iterable, - selector: (el: T) => number, + selector: (el: T, index: number) => number, ): T | undefined; /** * Returns the first element that is the largest value of the given function or @@ -63,7 +63,7 @@ export function maxBy( */ export function maxBy( array: Iterable, - selector: (el: T) => string, + selector: (el: T, index: number) => string, ): T | undefined; /** * Returns the first element that is the largest value of the given function or @@ -95,7 +95,7 @@ export function maxBy( */ export function maxBy( array: Iterable, - selector: (el: T) => bigint, + selector: (el: T, index: number) => bigint, ): T | undefined; /** * Returns the first element that is the largest value of the given function or @@ -127,21 +127,22 @@ export function maxBy( */ export function maxBy( array: Iterable, - selector: (el: T) => Date, + selector: (el: T, index: number) => Date, ): T | undefined; export function maxBy( array: Iterable, selector: - | ((el: T) => number) - | ((el: T) => string) - | ((el: T) => bigint) - | ((el: T) => Date), + | ((el: T, index: number) => number) + | ((el: T, index: number) => string) + | ((el: T, index: number) => bigint) + | ((el: T, index: number) => Date), ): T | undefined { let max: T | undefined; let maxValue: ReturnType | undefined; + let index = 0; for (const current of array) { - const currentValue = selector(current); + const currentValue = selector(current, index++); if (maxValue === undefined || currentValue > maxValue) { max = current; diff --git a/collections/max_by_test.ts b/collections/max_by_test.ts index e5b4b95a0e83..8f100855d5dc 100644 --- a/collections/max_by_test.ts +++ b/collections/max_by_test.ts @@ -136,3 +136,14 @@ Deno.test({ assertEquals(maxBy(input, (it) => new Date(it)), "February 1, 2022"); }, }); + +Deno.test({ + name: "maxBy() passes index to selector", + fn() { + const input = [4, 3, 2, 1]; + + const max = maxBy(input, (_, index) => index); + + assertEquals(max, 1); + }, +}); diff --git a/collections/max_of.ts b/collections/max_of.ts index 17a5101c91d6..972e3e4e0f0c 100644 --- a/collections/max_of.ts +++ b/collections/max_of.ts @@ -32,7 +32,7 @@ */ export function maxOf( array: Iterable, - selector: (el: T) => number, + selector: (el: T, index: number) => number, ): number | undefined; /** * Applies the given selector to all elements of the provided collection and @@ -65,16 +65,22 @@ export function maxOf( */ export function maxOf( array: Iterable, - selector: (el: T) => bigint, + selector: (el: T, index: number) => bigint, ): bigint | undefined; -export function maxOf number) | ((el: T) => bigint)>( +export function maxOf< + T, + S extends + | ((el: T, index: number) => number) + | ((el: T, index: number) => bigint), +>( array: Iterable, selector: S, ): ReturnType | undefined { let maximumValue: ReturnType | undefined; + let index = 0; for (const element of array) { - const currentValue = selector(element) as ReturnType; + const currentValue = selector(element, index++) as ReturnType; if (maximumValue === undefined || currentValue > maximumValue) { maximumValue = currentValue; diff --git a/collections/max_of_test.ts b/collections/max_of_test.ts index f93852aa6ada..16763d9d1c25 100644 --- a/collections/max_of_test.ts +++ b/collections/max_of_test.ts @@ -100,3 +100,14 @@ Deno.test("maxOf() handles infinity", () => { assertEquals(actual, Infinity); }); + +Deno.test({ + name: "maxBy() passes index to selector", + fn() { + const input = [4, 3, 2, 1]; + + const max = maxOf(input, (it, index) => it * index); + + assertEquals(max, 4); + }, +}); diff --git a/collections/min_by.ts b/collections/min_by.ts index dee32c2ee4df..28a1f09ae285 100644 --- a/collections/min_by.ts +++ b/collections/min_by.ts @@ -31,7 +31,7 @@ */ export function minBy( array: Iterable, - selector: (el: T) => number, + selector: (el: T, index: number) => number, ): T | undefined; /** * Returns the first element that is the smallest value of the given function or @@ -63,7 +63,7 @@ export function minBy( */ export function minBy( array: Iterable, - selector: (el: T) => string, + selector: (el: T, index: number) => string, ): T | undefined; /** * Returns the first element that is the smallest value of the given function or @@ -95,7 +95,7 @@ export function minBy( */ export function minBy( array: Iterable, - selector: (el: T) => bigint, + selector: (el: T, index: number) => bigint, ): T | undefined; /** * Returns the first element that is the smallest value of the given function or @@ -125,21 +125,22 @@ export function minBy( */ export function minBy( array: Iterable, - selector: (el: T) => Date, + selector: (el: T, index: number) => Date, ): T | undefined; export function minBy( array: Iterable, selector: - | ((el: T) => number) - | ((el: T) => string) - | ((el: T) => bigint) - | ((el: T) => Date), + | ((el: T, index: number) => number) + | ((el: T, index: number) => string) + | ((el: T, index: number) => bigint) + | ((el: T, index: number) => Date), ): T | undefined { let min: T | undefined; let minValue: ReturnType | undefined; + let index = 0; for (const current of array) { - const currentValue = selector(current); + const currentValue = selector(current, index++); if (minValue === undefined || currentValue < minValue) { min = current; diff --git a/collections/min_by_test.ts b/collections/min_by_test.ts index b52c338e411c..e4e2d411bfaf 100644 --- a/collections/min_by_test.ts +++ b/collections/min_by_test.ts @@ -137,3 +137,14 @@ Deno.test({ assertEquals(minBy(input, (it) => new Date(it)), "December 17, 1995"); }, }); + +Deno.test({ + name: "minBy() passes index to selector", + fn() { + const input = [4, 3, 2, 1]; + + const max = minBy(input, (_, index) => index); + + assertEquals(max, 4); + }, +}); diff --git a/collections/min_of.ts b/collections/min_of.ts index 0cbe51d9202a..51d1295776d5 100644 --- a/collections/min_of.ts +++ b/collections/min_of.ts @@ -32,7 +32,7 @@ */ export function minOf( array: Iterable, - selector: (el: T) => number, + selector: (el: T, index: number) => number, ): number | undefined; /** * Applies the given selector to all elements of the given collection and @@ -65,16 +65,22 @@ export function minOf( */ export function minOf( array: Iterable, - selector: (el: T) => bigint, + selector: (el: T, index: number) => bigint, ): bigint | undefined; -export function minOf number) | ((el: T) => bigint)>( +export function minOf< + T, + S extends + | ((el: T, index: number) => number) + | ((el: T, index: number) => bigint), +>( array: Iterable, selector: S, ): ReturnType | undefined { let minimumValue: ReturnType | undefined; + let index = 0; for (const element of array) { - const currentValue = selector(element) as ReturnType; + const currentValue = selector(element, index++) as ReturnType; if (minimumValue === undefined || currentValue < minimumValue) { minimumValue = currentValue; diff --git a/collections/min_of_test.ts b/collections/min_of_test.ts index 7f98528ea508..aec7eccc53af 100644 --- a/collections/min_of_test.ts +++ b/collections/min_of_test.ts @@ -100,3 +100,14 @@ Deno.test("minOf() handles minus infinity", () => { assertEquals(actual, -Infinity); }); + +Deno.test({ + name: "minOf() passes index to selector", + fn() { + const input = [4, 3, 2, 1]; + + const max = minOf(input, (it, index) => it * index); + + assertEquals(max, 0); + }, +}); diff --git a/collections/partition.ts b/collections/partition.ts index 1aa03a469cc9..ded7c4078391 100644 --- a/collections/partition.ts +++ b/collections/partition.ts @@ -29,7 +29,7 @@ */ export function partition( array: Iterable, - predicate: (el: T) => boolean, + predicate: (el: T, index: number) => boolean, ): [T[], T[]]; /** * Returns a tuple of two arrays with the first one containing all elements in @@ -64,17 +64,18 @@ export function partition( */ export function partition( array: Iterable, - predicate: (el: T) => el is U, + predicate: (el: T, index: number) => el is U, ): [U[], Exclude[]]; export function partition( array: Iterable, - predicate: (el: unknown) => boolean, + predicate: (el: unknown, index: number) => boolean, ): [unknown[], unknown[]] { const matches: Array = []; const rest: Array = []; + let index = 0; for (const element of array) { - if (predicate(element)) { + if (predicate(element, index++)) { matches.push(element); } else { rest.push(element); diff --git a/collections/partition_test.ts b/collections/partition_test.ts index 49a2c1c1a58f..73dee9f699c7 100644 --- a/collections/partition_test.ts +++ b/collections/partition_test.ts @@ -4,7 +4,7 @@ import { assertEquals } from "@std/assert"; import { partition } from "./partition.ts"; function partitionTest( - input: [Array, (element: I) => boolean], + input: [Array, (element: I, index: number) => boolean], expected: [Array, Array], message?: string, ) { @@ -73,3 +73,13 @@ Deno.test({ ); }, }); + +Deno.test({ + name: "partition() passes index to predicate some match", + fn() { + partitionTest( + [[2, 4, 6], (_, index) => index % 2 === 0], + [[2, 6], [4]], + ); + }, +}); diff --git a/collections/sort_by.ts b/collections/sort_by.ts index 82c6cd9a09b8..f467b823b85f 100644 --- a/collections/sort_by.ts +++ b/collections/sort_by.ts @@ -60,7 +60,7 @@ export type SortByOptions = { */ export function sortBy( array: readonly T[], - selector: (el: T) => number, + selector: (el: T, index: number) => number, options?: SortByOptions, ): T[]; /** @@ -98,7 +98,7 @@ export function sortBy( */ export function sortBy( array: readonly T[], - selector: (el: T) => string, + selector: (el: T, index: number) => string, options?: SortByOptions, ): T[]; /** @@ -138,7 +138,7 @@ export function sortBy( export function sortBy( array: readonly T[], - selector: (el: T) => bigint, + selector: (el: T, index: number) => bigint, options?: SortByOptions, ): T[]; /** @@ -177,16 +177,16 @@ export function sortBy( */ export function sortBy( array: readonly T[], - selector: (el: T) => Date, + selector: (el: T, index: number) => Date, options?: SortByOptions, ): T[]; export function sortBy( array: readonly T[], selector: - | ((el: T) => number) - | ((el: T) => string) - | ((el: T) => bigint) - | ((el: T) => Date), + | ((el: T, index: number) => number) + | ((el: T, index: number) => string) + | ((el: T, index: number) => bigint) + | ((el: T, index: number) => Date), options?: SortByOptions, ): T[] { const len = array.length; @@ -196,7 +196,7 @@ export function sortBy( array.forEach((element, index) => { indexes[index] = index; - const selected = selector(element); + const selected = selector(element, index); selectors[index] = Number.isNaN(selected) ? null : selected; }); diff --git a/collections/sort_by_test.ts b/collections/sort_by_test.ts index 5f2c84e4adfd..b7638d1de04c 100644 --- a/collections/sort_by_test.ts +++ b/collections/sort_by_test.ts @@ -474,3 +474,10 @@ Deno.test({ ]); }, }); + +Deno.test({ + name: "sortBy() passes index to selector", + fn() { + assertEquals(sortBy([2, 3, 1], (_, index) => -index), [1, 3, 2]); + }, +}); diff --git a/collections/sum_of.ts b/collections/sum_of.ts index 349a31268fd7..8e25914ca939 100644 --- a/collections/sum_of.ts +++ b/collections/sum_of.ts @@ -30,12 +30,13 @@ */ export function sumOf( array: Iterable, - selector: (el: T) => number, + selector: (el: T, index: number) => number, ): number { let sum = 0; + let index = 0; for (const i of array) { - sum += selector(i); + sum += selector(i, index++); } return sum; diff --git a/collections/sum_of_test.ts b/collections/sum_of_test.ts index f20b4ac3ae81..d270f13b4570 100644 --- a/collections/sum_of_test.ts +++ b/collections/sum_of_test.ts @@ -130,3 +130,11 @@ Deno.test("sumOf() handles Infinity", () => { assertEquals(actual, Infinity); }); + +Deno.test("sumOf() passes index to selector", () => { + const array = [1, 2, 3]; + + const actual = sumOf(array, (_, index) => index); + + assertEquals(actual, 3); +}); diff --git a/collections/take_last_while.ts b/collections/take_last_while.ts index ede00b95879c..129acd95b8ac 100644 --- a/collections/take_last_while.ts +++ b/collections/take_last_while.ts @@ -28,10 +28,10 @@ */ export function takeLastWhile( array: readonly T[], - predicate: (el: T) => boolean, + predicate: (el: T, index: number) => boolean, ): T[] { let offset = array.length; - while (0 < offset && predicate(array[offset - 1] as T)) offset--; + while (0 < offset && predicate(array[offset - 1] as T, offset - 1)) offset--; return array.slice(offset, array.length); } diff --git a/collections/take_last_while_test.ts b/collections/take_last_while_test.ts index 5fdc1cab5776..0028add0716d 100644 --- a/collections/take_last_while_test.ts +++ b/collections/take_last_while_test.ts @@ -55,3 +55,11 @@ Deno.test("takeLastWhile() returns the same array when all elements match the pr assertEquals(actual, [1, 2, 3, 4]); }); + +Deno.test("takeLastWhile() passes the index to the predicate", () => { + const arr = [1, 2, 3, 4]; + + const actual = takeLastWhile(arr, (_, index) => index > 1); + + assertEquals(actual, [3, 4]); +}); diff --git a/collections/take_while.ts b/collections/take_while.ts index fce2eb918484..283d8bc60995 100644 --- a/collections/take_while.ts +++ b/collections/take_while.ts @@ -31,12 +31,12 @@ */ export function takeWhile( array: readonly T[], - predicate: (el: T) => boolean, + predicate: (el: T, index: number) => boolean, ): T[] { let offset = 0; const length = array.length; - while (length > offset && predicate(array[offset] as T)) { + while (length > offset && predicate(array[offset] as T, offset)) { offset++; } diff --git a/collections/take_while_test.ts b/collections/take_while_test.ts index 1f8fc72d0e12..82f1176c5962 100644 --- a/collections/take_while_test.ts +++ b/collections/take_while_test.ts @@ -144,3 +144,11 @@ Deno.test("(unstable) takeWhile() handles a Map", () => { ["c", 3], ]); }); + +Deno.test("takeWhile() passes the index to the predicate", () => { + const arr = [1, 2, 3, 4]; + + const actual = takeWhile(arr, (_, index) => index < 1); + + assertEquals(actual, [1]); +});