从列表中获取唯一项目

dom*_*een 89 c# list unique

从列表中获取所有不同项目的最快/最有效方法是什么?

我有一个List<string>可能有多个重复项目,只想要列表中的唯一值.

Vin*_*jip 143

用一个HashSet<T>.例如:

var items = "A B A D A C".Split(' ');
var unique_items = new HashSet<string>(items);
foreach (string s in unique_items)
    Console.WriteLine(s);
Run Code Online (Sandbox Code Playgroud)

版画

A
B
D
C

  • "HashSet"不会维持任何排序,这可能是也可能不是OP的问题. (10认同)
  • 必须同意; 别人解决问题,你的解决原因:) (2认同)

Luk*_*keH 132

您可以使用该Distinct方法返回IEnumerable<T>不同的项目:

var uniqueItems = yourList.Distinct();
Run Code Online (Sandbox Code Playgroud)

如果您需要以a返回的唯一项目序列List<T>,则可以添加对以下内容的调用ToList:

var uniqueItemsList = yourList.Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)

  • @Noldorin:我知道这已经过时了,但它很容易出现在谷歌上而且你错了(至少,从.NET 4开始 - 我还没有检查旧版本).yourList.Distinct().ToList()执行一个枚举,new HashSet <T>(yourList).ToList()执行两个枚举.HashSet和Distinct的内部Set类的实现几乎完全相同.它们都使用GetHashCode,并且它们都使用IEqualityComparers(它们必须使用,因为相同的哈希码(通常)不保证相等的对象). (18认同)
  • @Noldorin:性能基准如何支持或反对我说的话?您可以通过在Reflector(或其他.NET反编译器)中提取System.Linq.Enumerable.DistinctIterator <T>和System.Linq.Set <T>来验证我所说的内容,而与相对性能无关. (3认同)
  • OP 正在寻找一种快速/高效的方法。不是这样的。调用“yourList.Distinct().ToList()”需要对可枚举进行两次完整迭代,并且另外基于“IEqualityComparer”,它比“GetHashCode”慢。 (2认同)

aku*_*aku 6

您可以使用LINQ的Distinct扩展方法


小智 6

在.Net 2.0中我非常肯定这个解决方案:

public IEnumerable<T> Distinct<T>(IEnumerable<T> source)
{
     List<T> uniques = new List<T>();
     foreach (T item in source)
     {
         if (!uniques.Contains(item)) uniques.Add(item);
     }
     return uniques;
}
Run Code Online (Sandbox Code Playgroud)

  • *请*使用比 List 具有更快随机访问速度的集合,例如 Dictionary 或 HashSet。因为目前,如果“source”包含 100,000 个具有许多重复项的项目,那么在 100,000 次迭代中的每一次,您都将扫描大约 100,000 个项目的列表,这意味着您正在扫描“100,000 * 100,000”项目的顺序。二次时间复杂度可能会变得相当慢。 (3认同)

Nol*_*rin 5

除了DistinctLINQ 的扩展方法之外,您还可以使用HashSet<T>通过集合初始化的对象。这很可能比 LINQ 方式更有效,因为它使用哈希码 ( GetHashCode) 而不是IEqualityComparer)。

事实上,如果适合您的情况,我首先会使用 aHashSet来存储物品。