* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the BSD-3-Clause License.
*
* This file is based on code from the @lumino/algorithm package:
* https://github.com/jupyterlab/lumino/tree/master/packages/algorithm
*
* Modifications made by Huawei Technologies Co., Ltd., 2025.
*/
export function* map<T, U>(
object: Iterable<T>,
fn: (value: T, index: number) => U
): IterableIterator<U> {
let index = 0;
for (const value of object) {
yield fn(value, index++);
}
}
export function find<T>(
object: Iterable<T>,
fn: (value: T, index: number) => boolean
): T | undefined {
let index = 0;
for (const value of object) {
if (fn(value, index++)) {
return value;
}
}
return undefined;
}
* The namespace for array-specific algorithms.
*/
export namespace ArrayExt {
export function findFirstIndex<T>(
list: ArrayLike<T>,
predicate: (item: T, index: number) => boolean,
begin = 0,
end = -1
): number {
const length = list.length;
if (length === 0) return -1;
const start = begin < 0 ? Math.max(0, length + begin) : Math.min(begin, length - 1);
const stop = end < 0 ? Math.max(0, length + end) : Math.min(end, length - 1);
const totalSteps = stop < start ? stop + 1 + (length - start) : stop - start + 1;
for (let offset = 0; offset < totalSteps; offset++) {
const index = (start + offset) % length;
if (predicate(list[index], index)) {
return index;
}
}
return -1;
}
export function removeAllWhere<T>(
items: T[],
predicate: (item: T, index: number) => boolean,
from = 0,
to = -1
): number {
const total = items.length;
if (total === 0) return 0;
const start = from < 0 ? Math.max(0, total + from) : Math.min(from, total - 1);
const end = to < 0 ? Math.max(0, total + to) : Math.min(to, total - 1);
let removed = 0;
for (let i = 0; i < total; ++i) {
const inRange =
start <= end
? i >= start && i <= end
: i >= start || i <= end;
if (inRange && predicate(items[i], i)) {
removed++;
} else if (removed > 0) {
items[i - removed] = items[i];
}
}
if (removed > 0) {
items.length = total - removed;
}
return removed;
}
}