Refactor partition and unzip into terminal functions

This commit is contained in:
2026-04-29 18:15:02 +02:00
parent a5866c08ff
commit e6d39a650e
3 changed files with 16 additions and 59 deletions

View File

@@ -148,7 +148,7 @@ export type Sequence<T> = {
filter<R extends T>(predicate: (it: T) => it is R): Sequence<R>
filter(predicate: (it: T) => boolean): Sequence<T>
partition(predicate: (it: T) => boolean): [Sequence<T>, Sequence<T>]
partition(predicate: (it: T) => boolean): [T[], T[]]
distinct(): Sequence<T>
distinctBy<K>(transform: (it: T) => K): Sequence<T>
@@ -170,7 +170,7 @@ export type Sequence<T> = {
associateBy<K>(transform: (it: T) => K): Sequence<[K, T]>
associateWith<V>(transform: (it: T) => V): Sequence<[T, V]>
zip<B>(items: Iterable<B>): Sequence<[T, B]>
unzip<A, B>(this: Sequence<[A, B]>): [Sequence<A>, Sequence<B>]
unzip<A, B>(this: Sequence<[A, B]>): [A[], B[]]
windowed(size: number, step?: number, partial?: boolean): Sequence<T[]>
chunked(size: number): Sequence<T[]>
@@ -354,8 +354,7 @@ function wrap<T>(value: Iterable<T> | (() => Iterable<T>)): Sequence<T> {
return wrap(() => filter(resolve(), predicate));
},
partition(predicate) {
const [a, b] = partition(resolve(), predicate);
return [wrap(a), wrap(b)];
return partition(resolve(), predicate);
},
distinct() {
return wrap(() => distinct(resolve()));
@@ -412,8 +411,7 @@ function wrap<T>(value: Iterable<T> | (() => Iterable<T>)): Sequence<T> {
return wrap(() => zip(resolve(), items));
},
unzip<A, B>() {
const [a, b] = unzip(resolve() as Iterable<[A, B]>);
return [wrap(a), wrap(b)];
return unzip(resolve() as Iterable<[A, B]>);
},
windowed(size, step, partial) {
return wrap(() => windowed(resolve(), size, step, partial));

View File

@@ -1,30 +1,9 @@
export function partition<T>(value: Iterable<T>, predicate: (it: T) => boolean): [() => Iterable<T>, () => Iterable<T>] {
const iterator = value[Symbol.iterator]();
let finished = false;
export function partition<T>(value: Iterable<T>, predicate: (it: T) => boolean): [T[], T[]] {
const t: T[] = [];
const f: T[] = [];
function next() {
const {value, done} = iterator.next();
if (done) finished = true;
else (predicate(value) ? t : f).push(value);
for (const it of value) {
if (predicate(it)) t.push(it);
else f.push(it);
}
function* T(): Iterable<T> {
let i = 0;
while (!finished || i < t.length) {
if (i < t.length) yield t[i++];
else next();
}
}
function* F(): Iterable<T> {
let i = 0;
while (!finished || i < f.length) {
if (i < f.length) yield f[i++];
else next();
}
}
return [T, F];
return [t, f];
}

View File

@@ -1,29 +1,9 @@
export function unzip<A, B>(value: Iterable<[A, B]>): [() => Iterable<A>, () => Iterable<B>] {
const iterator = value[Symbol.iterator]();
let finished = false;
const cache: [A, B][] = [];
function next() {
const {value, done} = iterator.next();
if (done) finished = true;
else cache.push(value);
export function unzip<A, B>(value: Iterable<[A, B]>): [A[], B[]] {
const resultA: A[] = [];
const resultB: B[] = [];
for (const [a, b] of value) {
resultA.push(a);
resultB.push(b);
}
function* A(): Iterable<A> {
let i = 0;
while (!finished || i < cache.length) {
if (i < cache.length) yield cache[i++][0];
else next();
}
}
function* B(): Iterable<B> {
let i = 0;
while (!finished || i < cache.length) {
if (i < cache.length) yield cache[i++][1];
else next();
}
}
return [A, B];
return [resultA, resultB];
}