Skip to content

Commit 70115ec

Browse files
committed
feat(asyncScanOnce): add asyncScanOnce function
1 parent 5927e6c commit 70115ec

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

index.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
asyncPushOnce,
4343
asyncRemoveFirstOnce,
4444
asyncRemoveOnce,
45+
asyncScanOnce,
4546
asyncSliceOnce,
4647
asyncSumOnce,
4748
asyncTailOnce,
@@ -589,3 +590,16 @@ test("asyncNoneNullOnce", async t => {
589590
t.is(await asyncNoneNullOnce(asyncIterator([undefined, 2, 3])), null);
590591
t.deepEqual(await asyncNoneNullOnce(asyncIterator([])), []);
591592
});
593+
594+
test("asyncScanOnce", async t => {
595+
t.deepEqual(
596+
await asyncToArrayOnce(asyncScanOnce(asyncIterator([1, 2, 3]), (a, e, i) => a + e * i, 0)),
597+
[0, 2, 8]
598+
);
599+
t.deepEqual(
600+
await asyncToArrayOnce(
601+
asyncScanOnce(asyncIterator(["a", "b", "c"]), (a, e, i) => `${a} ${i} ${e}`, "_")
602+
),
603+
["_ 0 a", "_ 0 a 1 b", "_ 0 a 1 b 2 c"]
604+
);
605+
});

index.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,3 +1071,33 @@ export async function asyncNoneNullOnce<T>(
10711071
}
10721072
return array;
10731073
}
1074+
1075+
export function asyncScanOnce<T, U>(
1076+
iterator: AsyncIteratorLike<T>,
1077+
f: (accumulator: U, element: T, index: number) => U | Promise<U>,
1078+
initial: U
1079+
): AsyncIterator<U> {
1080+
const it = asyncIterator(iterator);
1081+
let i = 0;
1082+
const during = (accumulator: U) => async (): Promise<IteratorResult<U>> => {
1083+
const element = await it.next();
1084+
if (element.done === true) {
1085+
next = after;
1086+
return after();
1087+
} else {
1088+
const value = await f(accumulator, element.value, i++);
1089+
next = during(value);
1090+
return {value};
1091+
}
1092+
};
1093+
const after = async (): Promise<IteratorResult<U>> => ({done: true, value: undefined});
1094+
let next = during(initial);
1095+
return {next: async () => next()};
1096+
}
1097+
1098+
export function asyncScanOnceFn<T, U>(
1099+
f: (accumulator: U, element: T, index: number) => U | Promise<U>,
1100+
initial: U
1101+
): (iterator: AsyncIteratorLike<T>) => AsyncIterator<U> {
1102+
return iterator => asyncScanOnce(iterator, f, initial);
1103+
}

0 commit comments

Comments
 (0)