Skip to content

Commit 06776fd

Browse files
committed
feat(asyncIndexOnce): add asyncIndexOnce function
1 parent 33ad70f commit 06776fd

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

index.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
asyncFilterOnce,
1313
asyncFold1Once,
1414
asyncFoldOnce,
15+
asyncIndexOnce,
1516
asyncInitialOnce,
1617
asyncIterator,
1718
asyncLastOnce,
@@ -415,3 +416,8 @@ test("asyncFoldOnce", async t => {
415416
test("asyncFold1Once", async t => {
416417
t.is(await asyncFold1Once(asyncIterator([1, 2, 3]), (a, e, i) => a + e * i), 9);
417418
});
419+
420+
test("asyncIndexOnce", async t => {
421+
t.is(await asyncIndexOnce(asyncIterator([1, 2, 3, 4, 3, 2, 1]), 2), 3);
422+
t.is(await asyncIndexOnce(asyncIterator([1, 2, 3, 4, 3, 2, 1]), 7), null);
423+
});

index.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {equal as defaultEqual} from "@softwareventures/ordered";
22
import type {AsyncIterableLike} from "@softwareventures/async-iterable";
3-
import {hasProperty} from "unknown";
43
import {asyncIterable} from "@softwareventures/async-iterable";
4+
import {hasProperty} from "unknown";
55
import {isNotNull} from "@softwareventures/nullable";
66

77
export type AsyncIteratorLike<T> =
@@ -672,3 +672,32 @@ export function asyncFold1OnceFn<T>(
672672
): (iterator: AsyncIteratorLike<T>) => Promise<T> {
673673
return async iterator => asyncFold1Once(iterator, f);
674674
}
675+
676+
export async function asyncIndexOnce<T>(
677+
iterator: AsyncIteratorLike<T>,
678+
index: number | Promise<number>
679+
): Promise<T | null> {
680+
const it = asyncIterator(iterator);
681+
const [i, e] = await Promise.all([index, it.next()] as const);
682+
683+
if (i < 0 || !isFinite(i) || Math.floor(i) !== i) {
684+
throw new RangeError("illegal index");
685+
}
686+
687+
let element = e;
688+
for (let j = 0; element.done !== true && j < i; ++j) {
689+
element = await it.next();
690+
}
691+
692+
if (element.done === true) {
693+
return null;
694+
} else {
695+
return element.value;
696+
}
697+
}
698+
699+
export function asyncIndexOnceFn<T>(
700+
index: number | Promise<number>
701+
): (iterator: AsyncIteratorLike<T>) => Promise<T | null> {
702+
return async iterator => asyncIndexOnce(iterator, index);
703+
}

0 commit comments

Comments
 (0)