sync
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { BitArray } from "../bitarray/index.js";
|
||||
import { asArray } from "../utils.js";
|
||||
import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomGenerator, RandomOptions } from "./types.js";
|
||||
import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomElement, RandomGenerator, RandomOptions } from "./types.js";
|
||||
|
||||
export const alwaysTrue: ElementPredicate = () => true;
|
||||
export const weightOfOne: ElementWeight = () => 1.0;
|
||||
@@ -45,9 +45,10 @@ function withDefaultOptions<T>(options: RandomOptions<T> | AsyncRandomOptions<T>
|
||||
};
|
||||
}
|
||||
|
||||
function _getRandomElement<T>(sequence: Iterable<T>, options: Required<RandomOptions<T>>) {
|
||||
function _getRandomElement<T>(sequence: Iterable<T>, options: Required<RandomOptions<T>>): RandomElement<T> {
|
||||
const { predicate, weight, random } = options;
|
||||
|
||||
let found = false;
|
||||
let result: T | undefined = undefined;
|
||||
let resultIndex = -1;
|
||||
let index = 0;
|
||||
@@ -66,22 +67,24 @@ function _getRandomElement<T>(sequence: Iterable<T>, options: Required<RandomOpt
|
||||
weightAcc += w;
|
||||
|
||||
if (random() * weightAcc < w) {
|
||||
found = true;
|
||||
result = element;
|
||||
resultIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { element: result, index: resultIndex };
|
||||
return { found, element: result, index: resultIndex } as RandomElement<T>;
|
||||
}
|
||||
|
||||
export function getRandomElement<T>(sequence: Iterable<T>, options?: RandomOptions<T>) {
|
||||
return _getRandomElement(sequence, withDefaultOptions(options));
|
||||
}
|
||||
|
||||
async function _getRandomElementAsync<T>(sequence: AsyncIterable<T>, options: Required<AsyncRandomOptions<T>>) {
|
||||
async function _getRandomElementAsync<T>(sequence: AsyncIterable<T>, options: Required<AsyncRandomOptions<T>>): Promise<RandomElement<T>> {
|
||||
const { predicate, weight, random } = options;
|
||||
|
||||
let found = false;
|
||||
let result: T | undefined = undefined;
|
||||
let resultIndex = -1;
|
||||
let index = 0;
|
||||
@@ -100,13 +103,14 @@ async function _getRandomElementAsync<T>(sequence: AsyncIterable<T>, options: Re
|
||||
weightAcc += w;
|
||||
|
||||
if (random() * weightAcc < w) {
|
||||
found = true;
|
||||
result = element;
|
||||
resultIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { element: result, index: resultIndex };
|
||||
return { found, element: result, index: resultIndex } as RandomElement<T>;
|
||||
}
|
||||
|
||||
export async function getRandomElementAsync<T>(sequence: AsyncIterable<T>, options?: AsyncRandomOptions<T>) {
|
||||
|
||||
@@ -4,7 +4,7 @@ export type ElementPredicate<T = any> = (index: number, obj: T) => boolean;
|
||||
export type ElementWeight<T = any> = (index: number, obj: T) => number;
|
||||
export type RandomGenerator = () => number;
|
||||
|
||||
export interface RandomOptions<T = any> {
|
||||
export type RandomOptions<T = any> = {
|
||||
predicate?: ElementPredicate<T>;
|
||||
weight?: ElementWeight<T>;
|
||||
random?: RandomGenerator;
|
||||
@@ -13,8 +13,20 @@ export interface RandomOptions<T = any> {
|
||||
export type MaybeAsyncElementPredicate<T = any> = MaybeAsyncFunction<ElementPredicate<T>>;
|
||||
export type MaybeAsyncElementWeight<T = any> = MaybeAsyncFunction<ElementWeight<T>>;
|
||||
|
||||
export interface AsyncRandomOptions<T = any> {
|
||||
export type AsyncRandomOptions<T = any> = {
|
||||
predicate?: MaybeAsyncElementPredicate<T>;
|
||||
weight?: MaybeAsyncElementWeight<T>;
|
||||
random?: RandomGenerator;
|
||||
};
|
||||
|
||||
type RandomElementFound<T> = {
|
||||
found: true;
|
||||
element: T;
|
||||
index: number;
|
||||
};
|
||||
type RandomElementNotFound = {
|
||||
found: false;
|
||||
element: undefined;
|
||||
index: -1;
|
||||
};
|
||||
export type RandomElement<T> = RandomElementFound<T> | RandomElementNotFound;
|
||||
|
||||
Reference in New Issue
Block a user