Compare commits
2 Commits
0fd0e3bada
...
afa56b7adf
| Author | SHA1 | Date | |
|---|---|---|---|
|
afa56b7adf
|
|||
|
1f7c246faf
|
@@ -11,7 +11,7 @@ import { AsyncRandomOptions } from "../random/types.js";
|
|||||||
import { selectionSorter } from "../sorting.js";
|
import { selectionSorter } from "../sorting.js";
|
||||||
import { Sequence } from "../sync/types.js";
|
import { Sequence } from "../sync/types.js";
|
||||||
import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncAction, MaybePromiseLike, MaybeAsyncGenerator, MaybePromise, MaybeAsyncIterable, MaybeAsyncTypePredicate } from "../types.js";
|
import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncAction, MaybePromiseLike, MaybeAsyncGenerator, MaybePromise, MaybeAsyncIterable, MaybeAsyncTypePredicate } from "../types.js";
|
||||||
import { asAsyncIterable } from "../utils.js";
|
import { asAsyncIterable, FindElementResult } from "../utils.js";
|
||||||
import { array, empty, wrap } from "./index.js";
|
import { array, empty, wrap } from "./index.js";
|
||||||
import { AsyncSequence, AsyncSequencePipeline, GroupedAsyncSequence, OrderedAsyncSequence } from "./types.js";
|
import { AsyncSequence, AsyncSequencePipeline, GroupedAsyncSequence, OrderedAsyncSequence } from "./types.js";
|
||||||
|
|
||||||
@@ -173,14 +173,14 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return n >= 0 ? n : Infinity;
|
return n >= 0 ? n : Infinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
async #tryGetFirst(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
async #tryGetFirst(predicate?: MaybeAsyncAnyPredicate<TElement>): Promise<FindElementResult<TElement>> {
|
||||||
if (predicate) {
|
if (predicate) {
|
||||||
for await (const element of this) {
|
for await (const element of this) {
|
||||||
if (await predicate(element)) {
|
if (await predicate(element)) {
|
||||||
return {
|
return {
|
||||||
found: true,
|
found: true,
|
||||||
element
|
element
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -190,13 +190,13 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return {
|
return {
|
||||||
found: true,
|
found: true,
|
||||||
element: next.value
|
element: next.value
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
found: false
|
found: false
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async first(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
async first(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
||||||
@@ -215,7 +215,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return result.found ? result.element : def;
|
return result.found ? result.element : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
async #tryGetLast(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
async #tryGetLast(predicate?: MaybeAsyncAnyPredicate<TElement>): Promise<FindElementResult<TElement>> {
|
||||||
let found = false;
|
let found = false;
|
||||||
let result: TElement | undefined = undefined;
|
let result: TElement | undefined = undefined;
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return {
|
return {
|
||||||
found,
|
found,
|
||||||
element: result
|
element: result
|
||||||
};
|
} as FindElementResult<TElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
async last(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
async last(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
||||||
@@ -255,9 +255,9 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return result.found ? result.element : def;
|
return result.found ? result.element : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
async #tryGetSingle(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
async #tryGetSingle(predicate?: MaybeAsyncAnyPredicate<TElement>): Promise<FindElementResult<TElement>> {
|
||||||
if (predicate) {
|
if (predicate) {
|
||||||
let result: { found: true; element: TElement; } | undefined = undefined;
|
let result: FindElementResult<TElement> | undefined = undefined;
|
||||||
|
|
||||||
for await (const element of this) {
|
for await (const element of this) {
|
||||||
if (await predicate(element)) {
|
if (await predicate(element)) {
|
||||||
@@ -265,13 +265,13 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return {
|
return {
|
||||||
found: false,
|
found: false,
|
||||||
reason: 2
|
reason: 2
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
found: true,
|
found: true,
|
||||||
element
|
element
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -279,10 +279,10 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
let next = await iterator.next();
|
let next = await iterator.next();
|
||||||
|
|
||||||
if (!next.done) {
|
if (!next.done) {
|
||||||
const result = {
|
const result: FindElementResult<TElement> = {
|
||||||
found: true,
|
found: true,
|
||||||
element: next.value
|
element: next.value
|
||||||
} as const;
|
};
|
||||||
|
|
||||||
next = await iterator.next();
|
next = await iterator.next();
|
||||||
|
|
||||||
@@ -293,14 +293,14 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return {
|
return {
|
||||||
found: false,
|
found: false,
|
||||||
reason: 2
|
reason: 2
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
found: false,
|
found: false,
|
||||||
reason: 1
|
reason: 1
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async single(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
async single(predicate?: MaybeAsyncAnyPredicate<TElement>) {
|
||||||
@@ -330,7 +330,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return result.found ? result.element : def;
|
return result.found ? result.element : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
async #tryElementAt(index: number) {
|
async #tryElementAt(index: number): Promise<FindElementResult<TElement>> {
|
||||||
let i = index;
|
let i = index;
|
||||||
|
|
||||||
for await (const element of this) {
|
for await (const element of this) {
|
||||||
@@ -338,7 +338,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return {
|
return {
|
||||||
found: true,
|
found: true,
|
||||||
element
|
element
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
i--;
|
i--;
|
||||||
@@ -346,7 +346,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
found: false
|
found: false
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async elementAt(index: number) {
|
async elementAt(index: number) {
|
||||||
@@ -693,18 +693,12 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
|||||||
return new CacheAsyncSequence<TElement>(this);
|
return new CacheAsyncSequence<TElement>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async asArray(): Promise<TElement[]> {
|
async asArray() {
|
||||||
return await this.toArray();
|
return await Array.fromAsync(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async toArray() {
|
async toArray() {
|
||||||
const array: TElement[] = [];
|
return await Array.fromAsync(this);
|
||||||
|
|
||||||
for await (const element of this) {
|
|
||||||
array.push(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toMap<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>): Promise<Map<TKey, TElement>>;
|
toMap<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>): Promise<Map<TKey, TElement>>;
|
||||||
@@ -1137,13 +1131,9 @@ abstract class BaseOrderedAsyncSequence<TElement> extends BaseAsyncSequence<TEle
|
|||||||
}
|
}
|
||||||
|
|
||||||
override async *iterator() {
|
override async *iterator() {
|
||||||
const arr: TElement[] = [];
|
const arr = await Array.fromAsync(this.#sequence);
|
||||||
|
|
||||||
for await (const obj of this.#sequence) {
|
await selectionSorter.sort(arr, this.#descending, this.#sorter);
|
||||||
arr.push(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
await selectionSorter.sort(arr, this.#descending, this.#sorter.comparison());
|
|
||||||
|
|
||||||
yield* arr;
|
yield* arr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,27 +2,47 @@ import { asArray } from "../utils.js";
|
|||||||
import { EmptyBitArray, BitArrayImpl } from "./impl.js";
|
import { EmptyBitArray, BitArrayImpl } from "./impl.js";
|
||||||
import { BitArray } from "./types.js";
|
import { BitArray } from "./types.js";
|
||||||
|
|
||||||
export const EMPTY = new EmptyBitArray();
|
namespace BitArray {
|
||||||
|
export const EMPTY: BitArray = new EmptyBitArray();
|
||||||
|
|
||||||
export function create(length: number): BitArray {
|
export function create(length: number): BitArray {
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
throw new Error("length < 0");
|
throw new Error("length < 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
return length === 0 ? EMPTY : new BitArrayImpl(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return length === 0 ? EMPTY : new BitArrayImpl(length);
|
export function from(bits: Iterable<boolean>) {
|
||||||
}
|
const arr = asArray(bits);
|
||||||
|
const result = create(arr.length);
|
||||||
|
|
||||||
export function from(bits: Iterable<boolean>): BitArray {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
const arr = asArray(bits);
|
result.set(i, arr[i]);
|
||||||
const result = create(arr.length);
|
}
|
||||||
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
return result;
|
||||||
result.set(i, arr[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
export function of(...bits: boolean[]) {
|
||||||
|
return from(bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function and(a: BitArray, b: BitArray) {
|
||||||
|
return a.copy().and(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function or(a: BitArray, b: BitArray) {
|
||||||
|
return a.copy().or(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function xor(a: BitArray, b: BitArray) {
|
||||||
|
return a.copy().xor(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function not(a: BitArray) {
|
||||||
|
return a.copy().not();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function of(...bits: boolean[]): BitArray {
|
export { BitArray };
|
||||||
return from(bits);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { create as createBitArray } from "../bitarray/index.js";
|
import { BitArray } from "../bitarray/index.js";
|
||||||
import { BitArray } from "../bitarray/types.js";
|
|
||||||
import { asArray } from "../utils.js";
|
import { asArray } from "../utils.js";
|
||||||
import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomGenerator, RandomOptions } from "./types.js";
|
import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomGenerator, RandomOptions } from "./types.js";
|
||||||
|
|
||||||
@@ -121,7 +120,7 @@ export class RandomPicker<T> {
|
|||||||
|
|
||||||
public constructor(elements: Iterable<T>, length: number, options?: RandomOptions<T>) {
|
public constructor(elements: Iterable<T>, length: number, options?: RandomOptions<T>) {
|
||||||
this.#elements = elements;
|
this.#elements = elements;
|
||||||
this.#flags = createBitArray(length);
|
this.#flags = BitArray.create(length);
|
||||||
this.#options = withDefaultOptions(mergeOptions({ predicate: i => this.#flags.get(i) }, options));
|
this.#options = withDefaultOptions(mergeOptions({ predicate: i => this.#flags.get(i) }, options));
|
||||||
|
|
||||||
this.reset();
|
this.reset();
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { createQueue } from "../queue.js";
|
|||||||
import { getRandomElement } from "../random/index.js";
|
import { getRandomElement } from "../random/index.js";
|
||||||
import { RandomOptions } from "../random/types.js";
|
import { RandomOptions } from "../random/types.js";
|
||||||
import { AnyPredicate, Converter, TypePredicate, BiConverter, Accumulator, Action } from "../types.js";
|
import { AnyPredicate, Converter, TypePredicate, BiConverter, Accumulator, Action } from "../types.js";
|
||||||
|
import { FindElementResult } from "../utils.js";
|
||||||
import { array, empty, wrap } from "./index.js";
|
import { array, empty, wrap } from "./index.js";
|
||||||
import { Sequence, GroupedSequence, OrderedSequence, SequencePipeline } from "./types.js";
|
import { Sequence, GroupedSequence, OrderedSequence, SequencePipeline } from "./types.js";
|
||||||
|
|
||||||
@@ -181,7 +182,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
return n >= 0 ? n : Infinity;
|
return n >= 0 ? n : Infinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tryGetFirst(predicate?: AnyPredicate<TElement>): { found: boolean, element?: TElement | undefined; } {
|
#tryGetFirst(predicate?: AnyPredicate<TElement>): FindElementResult<TElement> {
|
||||||
if (predicate) {
|
if (predicate) {
|
||||||
for (const element of this) {
|
for (const element of this) {
|
||||||
if (predicate(element)) {
|
if (predicate(element)) {
|
||||||
@@ -223,7 +224,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
return result.found ? result.element : def;
|
return result.found ? result.element : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tryGetLast(predicate?: AnyPredicate<TElement>): { found: boolean, element?: TElement; } {
|
#tryGetLast(predicate?: AnyPredicate<TElement>): FindElementResult<TElement> {
|
||||||
let found = false;
|
let found = false;
|
||||||
let result: TElement | undefined = undefined;
|
let result: TElement | undefined = undefined;
|
||||||
|
|
||||||
@@ -244,7 +245,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
return {
|
return {
|
||||||
found,
|
found,
|
||||||
element: result
|
element: result
|
||||||
};
|
} as FindElementResult<TElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
last(predicate?: AnyPredicate<TElement>) {
|
last(predicate?: AnyPredicate<TElement>) {
|
||||||
@@ -263,9 +264,9 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
return result.found ? result.element : def;
|
return result.found ? result.element : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tryGetSingle(predicate?: AnyPredicate<TElement>): { found: boolean, element?: TElement, reason?: number; } {
|
#tryGetSingle(predicate?: AnyPredicate<TElement>): FindElementResult<TElement> {
|
||||||
if (predicate) {
|
if (predicate) {
|
||||||
let result: { found: boolean; element: TElement; } | undefined = undefined;
|
let result: FindElementResult<TElement> | undefined = undefined;
|
||||||
|
|
||||||
for (const element of this) {
|
for (const element of this) {
|
||||||
if (predicate(element)) {
|
if (predicate(element)) {
|
||||||
@@ -287,7 +288,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
let next = iterator.next();
|
let next = iterator.next();
|
||||||
|
|
||||||
if (!next.done) {
|
if (!next.done) {
|
||||||
const result = {
|
const result: FindElementResult<TElement> = {
|
||||||
found: true,
|
found: true,
|
||||||
element: next.value
|
element: next.value
|
||||||
};
|
};
|
||||||
@@ -319,7 +320,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
}
|
}
|
||||||
|
|
||||||
let reason: string;
|
let reason: string;
|
||||||
switch (result.reason!) {
|
switch (result.reason) {
|
||||||
case 1:
|
case 1:
|
||||||
reason = "No element was found.";
|
reason = "No element was found.";
|
||||||
break;
|
break;
|
||||||
@@ -338,7 +339,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
return result.found ? result.element : def;
|
return result.found ? result.element : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tryElementAt(index: number) {
|
#tryElementAt(index: number): FindElementResult<TElement> {
|
||||||
let i = index;
|
let i = index;
|
||||||
|
|
||||||
for (const element of this) {
|
for (const element of this) {
|
||||||
@@ -346,7 +347,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
return {
|
return {
|
||||||
found: true,
|
found: true,
|
||||||
element
|
element
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
i--;
|
i--;
|
||||||
@@ -354,7 +355,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
found: false
|
found: false
|
||||||
} as const;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
elementAt(index: number) {
|
elementAt(index: number) {
|
||||||
@@ -1164,11 +1165,7 @@ export abstract class BaseOrderedSequence<TElement> extends BaseSequence<TElemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
override *iterator() {
|
override *iterator() {
|
||||||
const arr: TElement[] = [];
|
const arr = Array.from(this.#sequence);
|
||||||
|
|
||||||
for (const obj of this.#sequence) {
|
|
||||||
arr.push(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.#sorter) {
|
if (this.#sorter) {
|
||||||
arr.sort((this.#descending ? this.#sorter.reverse() : this.#sorter).comparison());
|
arr.sort((this.#descending ? this.#sorter.reverse() : this.#sorter).comparison());
|
||||||
|
|||||||
11
src/utils.ts
11
src/utils.ts
@@ -49,3 +49,14 @@ const _emptyIterableIterator = new class EmptyIterableIterator implements Iterab
|
|||||||
export function emptyIterableIterator<T>(): IterableIterator<T> {
|
export function emptyIterableIterator<T>(): IterableIterator<T> {
|
||||||
return _emptyIterableIterator;
|
return _emptyIterableIterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FindElementSuccess<T> = {
|
||||||
|
found: true;
|
||||||
|
element: T;
|
||||||
|
};
|
||||||
|
type FindElementFail = {
|
||||||
|
found: false;
|
||||||
|
element?: never;
|
||||||
|
reason?: number;
|
||||||
|
};
|
||||||
|
export type FindElementResult<T> = FindElementSuccess<T> | FindElementFail;
|
||||||
|
|||||||
Reference in New Issue
Block a user