List 如何在保留顺序的同时删除列表中的重复元素?

List 如何在保留顺序的同时删除列表中的重复元素?,list,collections,dart,List,Collections,Dart,我刚才看到了 一个集合只有唯一的元素(没有顺序),但有时我需要一个有序的列表,我想删除所有重复的元素(第二次出现的元素,例如字符串,应该从列表中删除) 列表的原始输入:a,B,C,B,D,a应产生a,B,C,D。我需要遵守秩序。像B、A、D、C这样的结果对我没有帮助。您自己很容易实现: Iterable distinct(Iterable i){ 变量集=新集(); 返回i.where((e){ var isNew=!set.contains(e); 增加(e); 返回是新的; }); 如果S

我刚才看到了

一个集合只有唯一的元素(没有顺序),但有时我需要一个有序的列表,我想删除所有重复的元素(第二次出现的元素,例如字符串,应该从列表中删除)


列表的原始输入:
a,B,C,B,D,a
应产生
a,B,C,D
。我需要遵守秩序。像
B、A、D、C这样的结果对我没有帮助。

您自己很容易实现:

Iterable distinct(Iterable i){
变量集=新集();
返回i.where((e){
var isNew=!set.contains(e);
增加(e);
返回是新的;
});
如果
Set.add()
返回一个bool,指示是否修改了集合,那就更好了:

Iterable distinct(Iterable i){
变量集=新集();
返回i.where((e)=>set.add(e));
}
当然,您可以将功能请求错误归档

编辑:正如Florian指出的,上述解决方案仅在返回的
Iterable
仅使用一次时有效。后续使用将返回
Iterator
s,其中不包含任何元素,因为第一次使用时已看到偶数元素

为了解决这个问题,我们需要为从返回的
Iterable
创建的每个
Iterator
保留一个访问集,而不仅仅是为
Iterable
保留一个访问集。我们可以通过创建
Iterable
Iterator
子类,如
WhereIterable

Iterable distinct(Iterable i)=>新的distinctrable(i);
类可区分扩展可区分{
最终可测试_可测试;
可区分的(这是可区分的);
迭代器获取迭代器{
返回新的differenticaterator(_iterable.iterator);
}
}
类特殊迭代器扩展迭代器{
最终迭代器_迭代器;
最终集_=新集();
区分迭代器(this.\u迭代器);
bool moveNext(){
while(_iterator.moveNext()){
如果(!_visted.contains(_iterator.current)){
_add(_iterator.current);
返回true;
}
}
返回false;
}
E get current=>_iterator.current;
}

是的,这要长得多,但对于多个use finite
Iterable
s和一个use infinite
Iterable
s,它都能正常工作。infinite Iterable用例很容易出现内存问题,这是一个不将其包含在核心库中的理由,并迫使开发人员做出一些关于他们到底需要什么的决定

贾斯汀·法格纳尼已经给出了一个很好的答案。下面是另一个:

Iterable distinct(Iterable i){
var map=newlinkedhashmap();
i、 forEach((x){map[x]=true;});
return map.keys;//map.keys.toList()将为GC释放映射。
}

使用
toSet
然后使用
toList

  var ids2 = ["A", "B", "C", "B", "D", "A"];
  var result = ids2.toSet().toList();

[A, B, C, D]

使用泛型和生成器,您可以生成一个可用于任何类型的可重用项的函数

Iterable<T> distinct<T>(Iterable<T> elements) sync* {
  final visited = <T>{};
  for (final el in elements) {
    if (visited.contains(el)) continue;
    yield el;
    visited.add(el);
  }
}

[“A”、“B”、“C”、“B”、“D”、“A]”的用法

为什么没有这样的功能?因为Dart团队做出了同样的决定,不提供这样的功能,就像他们之前的许多标准库的设计者一样。你想要这样的功能吗?那么你要么自己实现,要么找一个库来为你实现。这个问题的目的是什么?找出为什么没有作为标准库的一部分,或者找出如何做到这一点,而不考虑这一事实?列表上的所有操作都将是
O(n^2)
。为了获得更好的边界,将在内部使用排序或集合。这应该很容易使用集合和探测为此创建一个帮助函数(如果不存在的话)。(至于为什么这些没有在列表中定义——不是建设性的。)可能的重复(注意如何删除不相关的问题并更改标题使这个问题成为“建设性的”。它也是重复的,但现在可能会有更少的反对票。)我想知道缺少该函数的原因是什么。答案是thx。我想我需要像1年前一样的distinct(),我写了我自己的RemovedUpplicates()。我想他们需要一些时间来实现“官方”的dart-distinct()。现在我听说它仍然不可用。我只是想知道:为什么?还有很多东西还没有。你提交了功能请求吗?解决方案有效,但只有在迭代器只使用一次的情况下才有效。不小心按下,然后在更新注释之前花费了太多时间……它只工作一次的原因是,返回的iterabl每次使用时,e都会重做“where”。但“set”不会重置。一个简单的解决方案是使用“.toList()”.强制计算筛选器。棘手,@FlorianLoitsch,感谢您指出问题。我原以为这会保留惰性,但我看到了问题。这就是为什么这些实用程序应该位于核心库中:)我将尝试添加一个正确的版本。注意:LinkedHashMap现在位于dart:集合中,我们可能很快将添加InsertionOrderedSet。如果我的列表中有类的实例呢?例如
[Foo实例],[Foo实例],[Foo实例]
?是否可以在保留对象实例的同时删除重复项?
extension IterableDistinctExt<T> on Iterable<T> {
  Iterable<T> distinct() sync* {
    final visited = <T>{};
    for (final el in this) {
      if (visited.contains(el)) continue;
      yield el;
      visited.add(el);
    }
  }
}