For AI agents: the complete documentation index is available at /tc39-atlas/llms.txt, the full documentation bundle is available at /tc39-atlas/llms-full.txt, and this page is available as Markdown at /tc39-atlas/proposals/stage/1/proposal-iterator-unique.md.
  • 简体中文
  • Iterator unique S1

    中文标题:迭代器唯一值

    提案概览
    提案速览

    该提案旨在为 Iterator.prototype 添加一个方法,从任何迭代器生成唯一值,解决现有工具对迭代器去重的困难。所选方案是 uniqBy,它接受一个可选的映射器作为唯一性标准。

    Note

    以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。

    迭代器唯一值

    这是一个 TC39 提案,旨在从任何迭代器生成唯一值的迭代器。

    阶段: 1

    参见 2024年1月向委员会做的演示

    动机

    从任何类型的集合中去除重复项是一种常见操作。对于迭代器来说,这并不容易实现。

    对于某些可迭代对象,你可以这样做:

    let uniques = new Set(iter).values();

    但这有一些缺点:

    1. 在产生任何结果之前会消耗整个迭代器。
    2. 不适用于无限迭代器。
    3. 当底层迭代器产生 -0 时,会产出 0。
    4. 不能同时产出 0 和 -0。
    5. 不适用于不可迭代的迭代器。

    更好的解决方案编写起来要困难得多,并且不能很好地与链式操作配合,因为它需要一组用于状态的附加变量。

    let objSeen = new WeakSet,
      primSeen = new Set,
      seenNegZero = false;
    
    let uniques = iter.filter(e => {
      if (e === 0 && 1/e < 0) {
        if (seenNegZero) return false;
        seenNegZero = true;
        return true;
      }
      let seen = Object(e) === e ? objSeen : primSeen;
      if (seen.has(e)) return false;
      seen.add(e);
      return true;
    });

    更糟糕的是,当你希望根据某种应用的变换来去重时,你需要用成对的 map 和拆对的 map 包围 filter

    let uniques = iter
      .map(e => [e, f(e)])
      .filter([, criteria] => { ... })
      .map(([e]) => e);

    所选方案

    Iterator.prototype.uniqBy,它接受一个可选的映射器。

    let uniques = iter.uniqBy();
    let uniques = iter.uniqBy(obj => obj.field);

    设计空间

    • 对于复合键仍然没有好的解决方案,但这是一个普遍未解决的问题
    • 映射器?比较器?两者都要?还是都不要?
      • 是分开的方法还是带有可选参数的组合?
      • 映射器是否会被传入索引?
    • 命名:distinct 也很常见

    先例

    其他语言

    语言简单 API带比较器带映射
    Clojurecoredistinct----
    ElmList.Extraunique--uniqueBy
    HaskellData.ListnubnubBy--
    JavaStreamdistinct----
    KotlinSequencedistinct--distinctBy
    .NETSystem.LinqDistinctDistinct, DistinctByDistinctBy
    PHParrayarray_unique----
    Pythonmore-itertoolsunique_everseen--unique_everseen
    RubyEnumerableuniq--uniq
    RustIterator------
    ScalaSeqdistinct--distinctBy
    ShellGNU coreutilsuniq----
    SwiftSequence------

    JS 库

    简单 API带比较器带映射
    extra-iterableuniqueuniqueunique
    iter-opsdistinct--distinct
    iter-toolsdistinct--distinct
    itertools-tsdistinct--distinct
    Lodash / UnderscoreuniquniqWithuniqBy
    RamdauniquniqWithuniqBy
    sequencydistinct--distinctBy
    wuunique----