import type { As, Copy, Fn, Into, NonZeroPositiveInteger, Option, OrdResult, OrdSelf, Result, Sum, TryAble } from '@chzky/core'; import type { VectorInfiniteLengthError, VertorUsedError } from './about.error.js'; export declare enum VectorState { DONE = 0, PEND = 1 } export declare enum VectorSize { INFINITY = 0, LIMITED = 1, UNKNOWN = 2 } /** ## `Vector` : 具有[惰性求值](https://zh.wikipedia.org/zh-hant/%E6%83%B0%E6%80%A7%E6%B1%82%E5%80%BC)的可迭代数据结构 + `Vector`是一种具有惰性求值的可迭代数据结构,其内部的数据只有在`被消费`的时候才会进行计算.可以有效的减少不必要的计算,提高性能 + 相比`Array`增加了许多的链式操作`API`,可以方便的对数据进行处理 + 允许创建无限列表 ### `@done` 标签的方法 + 如果Vector的方法有`@done`标签,则表示此方法会消费Vector,消费后的Vector将无法再次被使用,如果再次使用则会抛出{@link VertorUsedError}错误 + 并且如果Vector的长度为无限,调用`@done`标签的方法,则会抛出{@link VectorInfiniteLengthError}错误 ### 性能场景 1. 对于数据量大但是需求量少的场景有着很好的性能优势,常见的场景譬如:列表分页处理,数据筛选等 2. 如果此时一个数据需要完全遍历才能得到结果,那么`Vector`的性能会比普通的迭代器差 @example Usage : 惰性求值的`Vector`可以有效的减少不必要的计算,提高性能 ```ts // Test Data const name_r = ['jio', 'jiojio', 'dio', 'diojio'] const address = ['防抖华云', '公园花园', '秀琼花园'] const arr = Array.from({ length: 100000 }, (_, i) => ({ name: name_r[i % name_r.length], id: i, address: address[i % address.length], is: false, })) // 使用 take()进行惰性求值 Vec(arr) .map((i) => { if (i.id % 2 === 0) i.is = true return i }) .filter((i) => i.name == 'dio') .filter((i) => i.is) .drop(10) .map((i) => ({ ...i, name: i.address + '-' + i.name })) .take(500) .collect() //==> 514.72 µs/iter // 使用迭代器方法进行求值 arr .map((i) => { if (i.id % 2 === 0) i.is = true return i }) .filter((i) => i.name == 'dio') .filter((i) => i.is) .slice(10) .map((i) => ({ ...i, name: i.address + '-' + i.name })) .slice(500) //==> 5.16 ms/iter ``` @category Class */ export interface Vector extends Copy, Sum, TryAble<'collect'>, As, 'array'>, Into { /** ### `state` : Vector所属状态 */ state: VectorState; /** ### `size` : Vector可能的最大长度状态 */ size: VectorSize; /** @PEND */ /** ### `take` : 只取前n个元素 @example Usage ```ts Vec([1, 2, 3, 4, 5]).take(2).collect() //==> [1,2] ``` @tips 当迭代的数据越多,同时拿取的数据越少,`take`的性能越好 */ take: (num: NonZeroPositiveInteger) => Vector; /** ### `stop` : 条件停止迭代 + 当执行条件为真时停止迭代 @example Usage ```ts Vec([1, 2, 3, 4, 5]).stop_for((i) => i > 3).collect() //==> [1,2,3,4] ``` */ stop_for: (cb: Fn) => Vector; /** ### `map` : 原Vector中的每个元素都调用一次提供的函数后的返回值组成一个新的Vector。 */ map: (cb: Fn) => Vector; /** ### `filter` : 元素过滤 */ filter: (cb: Fn) => Vector; /** ### `filter_map` : 过滤并映射 + 规则 : 返回值为`None`则进行过滤;返回值为`Some`则进行映射 */ filter_map: (cb: Fn>) => Vector; /** ### `inspect` : 遍历元素;类似于`each`,但是不会消费Vector @example Usage ```ts Vec([1, 2, 3, 4, 5]).inspect(console.log).collect() // 1 // 2 // 3 // 4 // 5 ``` */ inspect: (cb: Fn) => Vector; /** ### `drop` : 跳过前n个元素 @example Usage ```ts Vec([1, 2, 3, 4, 5]).drop(2).collect() //==> [3,4,5] ``` */ drop: (num: NonZeroPositiveInteger) => Vector; /** ### `step_by` : 取符合步进规律的元素 @example Usage ```ts // 取 index % 2 === 0 的值 Vec([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).step_by(2).collect() //==> [1,3,5,7,9] ``` */ step_by: (step: NonZeroPositiveInteger) => Vector; /** ### `chain` : 将两个Vector进行拼接 @example Usage ```ts Vec([1, 2, 3]).chain(Vec([4, 5, 6])).collect() //==> [1,2,3,4,5,6] ``` */ chain: (other: Vector) => Vector; /** ### `zip` : 将两个Vector进行拼接,返回的长度以最小的长度为准,多余的长度将被裁剪掉 @example Usage ```ts Vec([1, 2, 3]).zip(Vec([4, 5, 6,7])).collect() //==> [[1,4],[2,5],[3,6]] ``` */ zip: (other: Vector) => Vector<[T, R]>; /** ### `unzip` : `zip`函数的相反操作,将一个`Vector<[A,B]>`拆分成两个`[Vector, Vector]` @example Usage ```ts Vec([[1, 2], [3, 4], [5, 6]]).unzip() //==> [[1,3,5],[2,4,6]] ``` */ unzip: () => T extends [infer A, infer B] ? [Vector, Vector] : never; /** ### `cycle` : 将数据进行无限循环(遍历到末尾然后从头开始继续遍历) @example Usage ```ts Vec([1, 2, 3]).cycle().take(10).collect() //==> [1,2,3,1,2,3,1,2,3,1] ``` */ cycle: () => Vector; /** ### `interleave` : 将`R`在`Vector`中进行交叉插入 @example Usage ```ts Vec([1, 2, 3]).interleave(0).collect() //==> [1,0,2,0,3] ``` */ intersperse: (separator: R) => Vector; /** @DONE */ /** ### `collect` : 将`Vector`转换为`Array` + 如果Vector的长度为无限,则会抛出`VectorInfiniteLengthError`异常 + 如果Vector已经被消费,则会抛出`VertorUsedError`异常 + 如果想避免异常直接抛出,使用`try_collect` @done : 此操作会将会消费Vector */ collect: () => Array; /** ### `each` : 遍历元素 @done : 此操作会将会消费Vector */ each: (cb: Fn) => void; /** ### `try_collect` : 对于可能出错的情况collect进行封装 @example Usage ```ts Vec([1, 2, 3, 4, 5]).try_collect() //==> Ok([1,2,3,4,5]) Vec([]).try_collect() //==> Ok([]) Vec([1, 2, 3]).cycle().try_collect() //==> Err(VectorInfiniteLengthError) Vec([1, 2, 3]).collect().try_collect() //==> Err(VertorUsedError) ``` @done : 此操作会将会消费Vector */ try_collect: () => Result, VectorInfiniteLengthError | VertorUsedError | unknown>; /** ### `collect_into` : 将Vector转换为目标数组并追加到`target`数组上 @example Usage ```ts const target = [1, 2, 3] Vec([4, 5, 6]).collect_into(target) //==> [1,2,3,4,5,6] ``` @done : 此操作会将会消费Vector */ collect_into: (target: Array) => Array; /** ### `reduce` : 通过重复应用缩减操作,将元素缩减为单个元素。 + 如果没有传递`init`参数,则第一个元素作为初始值 - 如果Vector为空则返回`None`,否则返回`Some` @done : 此操作会将会消费Vector */ reduce(cb: (acc: T | R, cur: T) => R): Option; reduce(cb: (acc: R, cur: T) => R, init: R): R; reduce(cb: (acc: T, cur: T) => T, init: T): T; /** ### `join` : 将Vector按照`separator`转化为`string` @example Usage ```ts Vec(['a', 'b', 'c']).join(',') //==> 'a,b,c' ``` @tips 如果Vector的长度为无限,则会抛出异常 @done 此操作会将会消费Vector */ join: (separator: string) => string; /** ### `partition` : 将Vector按照条件进行二元分割 @example Usage ```ts Vec([1, 2, 3, 4, 5]).partition((i) => i % 2 === 0) //==> [[2,4],[1,3,5]] ``` @done 此操作会将会消费Vector */ partition: (cb: Fn) => [Array, Array]; /** ### `next_chunk` : 消费并获取下一个元素 @example Usage ```ts const vec = Vec([1, 2]) vec.next_chunk() //==> Some(1) vec.next_chunk() //==> Some(2) vec.next_chunk() //==> None ``` @done : 此操作会将会`可能会`消费Vector */ next_chunk: () => Option; /** ### `position` : 返回满足条件的元素的位置 @example Usage ```ts Vec([1, 2, 3, 4, 5]).position(3) //==> Some(2) Vec([1, 2, 3, 4, 5]).position(6) //==> None ``` @done 此操作会将会消费Vector */ position: (predicate: T) => Option; /** ### `last` : 返回Vector最后一个元素 @example Usage ```ts Vec([1, 2, 3, 4, 5]).last() //==> Some(5) Vec([]).last() //==> None assert.throw(() => Vec([1, 2, 3]).cycle().last(), VectorInfiniteLengthError) ``` @tips 如果Vector的长度为无限,则会抛出异常 @done 此操作会将会消费Vector */ last: () => Option; /** ### `min` : 返回比较结果后最小的元素 + 要求 : 泛型`T`实现`OrdSelf`接口 @example Usage ```ts class Score implements OrdSelf { constructor( public chinese: number, public math: number, public english: number, ) {} equals(val: Score): boolean { throw this.chinese === val.chinese && this.math === val.math && this.english === val.english } compare(val: Score): OrdResult { const total = this.chinese + this.math + this.english const ittoal = val.chinese + val.math + val.english return total === ittoal ? OrdResult.EQ : total > ittoal ? OrdResult.GT : OrdResult.LT } } const xiaoming = new Score(1, 2, 3) const xiaomi = new Score(2, 3, 4) const xiaojun = new Score(3, 4, 5) const class_score_vec = Vec([xiaoming, xiaomi, xiaojun]) assert.equal(class_score_vec.min(), xiaoming) ``` @done 此操作会将会消费Vector */ min: () => T extends OrdSelf ? T : never; /** ### `min_by` : 根据cb返回比较结果后最小的元素 @example Usage ```ts class Score { constructor( public chinese: number, public math: number, public english: number, ) {} } const xiaoming = new Score(1, 2, 3) const xiaomi = new Score(2, 3, 4) const xiaojun = new Score(3, 4, 5) const class_score_vec = Vec([xiaoming, xiaomi, xiaojun]) const minby = class_score_vec.clone().min_by((now, min) => { const now_total = now.chinese + now.math + now.english const min_total = min.chinese + min.math + min.english return now_total === min_total ? OrdResult.EQ : now_total > min_total ? OrdResult.GT : OrdResult.LT }) assert.equal(minby, xiaoming) ``` @done 此操作会将会消费Vector */ min_by: (cb: (now: T, min: T) => OrdResult) => T; /** ### `max` : 返回比较结果后最大的元素 + 要求 : `T`实现`OrdSelf` @done : 此操作会将会消费Vector */ max: () => T extends OrdSelf ? T : never; /** ### `max_by` : 返回比较结果后最大的元素 @done : 此操作会将会消费Vector */ max_by: (cb: Fn) => T; /** ### `find` : 生成的第一个满足提供的测试函数的元素。如果没有值满足测试函数,则返回 None @example Usage ```ts Vec([1, 2, 3, 4, 5]).find((i) => i % 2 === 0) //==> Some(2) Vec([1, 2, 3, 4, 5]).find((i) => i > 10) //==> None ``` @done : 此操作会将会消费Vector */ find: (cb: Fn) => Option; /** ### `every` : 如果数组中的每个元素都满足提供的测试函数,则返回 `true`,否则返回 `false` @example Usage ```ts Vec([1, 2, 3, 4, 5]).every((i) => i % 2 === 0) //==> false Vec([2, 4, 6, 8]).every((i) => i % 2 === 0) //==> true ``` @done : 此操作会将会消费Vector */ every: (cb: Fn) => boolean; /** ### `some` : 如果数组中至少有一个元素满足提供的测试函数,则返回 `true`,否则返回 `false` @example Usage ```ts Vec([1, 2, 3, 4, 5]).some((i) => i % 2 === 0) //==> true Vec([1, 3, 5, 7]).some((i) => i % 2 === 0) //==> false ``` @done : 此操作会将会消费Vector */ some: (cb: Fn) => boolean; /** ### `sum` : 返回Vector的和 + 只有当`T`为number类型的时候才生效;否则会抛异 + 如果Vector的长度为无限,则会抛出异常 @example Usage ```ts Vec([1, 2, 3, 4, 5]).sum() //==> 15 ``` @done : 此操作会将会消费Vector */ sum: () => T extends number ? T : never; /** ### `nth` : 返回Vector的第n个元素 @example Usage ```ts Vec([1, 2, 3, 4, 5]).nth(2) //==> Some(3) Vec([1, 2, 3, 4, 5]).nth(6) //==> None ``` @done : 此操作会将会消费Vector */ nth: (n: number) => Option; /** ### `size_hint` : 返回`Vertor`剩余长度的范围 + 返回的结果为: `[lower, upper]` ,表示一个剩余长度范围. 其中`lower`为迭代器的最低长度,`upper`为`Option`类型,表示迭代器的最大长度,如果为`None`则表示迭代器长度为无限长度 + 对于任意`Vertor`,其`size_hint`返回的结果都满足`[0,None]` */ size_hint: () => [number, Option]; /** ### `count` : 返回`Vector`的长度 ,如果长度为无限则返回`Infinity` @example Usage ```ts Vec([1, 2, 3, 4, 5]).count() //==> 5 Vec([1, 2, 3, 4, 5]).cycle().count() //==> Infinity ``` @done : 此操作会将会消费Vector */ count: () => number; /** ### `clone` : 克隆一个`Vector`,包括其消费状态 @example Usage ```ts const vec = Vec([1, 2, 3, 4, 5]) const vec2 = vec.clone() vec.collect() //==> [1,2,3,4,5] vec2.map(i=>i+1).collect() //==> [2,3,4,5,6] ``` */ clone: () => Vector; /** ### `add_generator` : 增加自定义的生成器 @example Usage ```ts Vec([1, 2, 3, 4, 5]).add_generator(function* (gen) { for (const i of gen) { yield i yield i } }).collect() //==> [1,1,2,2,3,3,4,4,5,5] ``` @example 配合`@chzky/std`中`*_generator`进行简化操作 ```ts Vec([]).add_generator(number_generator(1, 10)).collect() //==> [1,2,3,4,5,6,7,8,9] Vec(add_generator(number_generator(1, 10))).collect() //==> [1,2,3,4,5,6,7,8,9] ``` */ add_generator: (gencb: Fn, Generator>) => Vector; /** ### `stream` : 流式遍历,根据回调判断是否加载下一条数据 @example Usage ```ts const seq = assert_sequence() await Vec([1, 2, 3, 4, 5]).stream((i, next) => { setTimeout(() => { seq(i) next() }, 500) }) ``` @example Use cancel ```ts //use cancel() let idx = 0 await vec.clone().stream((i, next, cancel) => { setTimeout(() => { if (idx >= 2) return cancel() idx++ next() }, 50) }) assert(idx === 2) ``` @done : 此操作会将会消费Vector */ stream: (cb: (item: T, next: Fn, cancel: Fn) => unknown) => Promise; [Symbol.iterator](): Generator; } export interface VectorConstructor { (from: ArrayLike): Vector; (from: Generator | Iterable, finite?: boolean): Vector; /** ### `is` : 运行时判断{@linkcode Vector} */ is(val: unknown): val is Vector; } //# sourceMappingURL=interface.d.ts.map