如何从列表<T>中删除重复值,同时保留元素的原始顺序?

问题描述 投票:0回答:2

说明:

我有一个 C# 列表,其中包含重复值。我想删除所有重复的值,以便仅每个值的第一个保留在列表中,并且列表中元素的顺序不会改变。有没有有效的方法来做到这一点?

List<int> numbers = new List<int> { 1, 2, 3, 2, 4, 3, 5 };

删除重复值后,列表应如下所示:

{ 1, 2, 3, 4, 5 }

使用 HashSet 是正确的方法还是有其他方法来保留列表的顺序?提供指导或示例代码。

我首先使用HashSet去除重复值,但是发现这个方法改变了元素的顺序。然后我尝试使用 for 循环和临时列表来跟踪唯一值,但这种方法似乎有点复杂且效率低下。

我希望使用一种更简单、更高效的方法来删除重复值,同时保留列表中元素的原始顺序。

c#
2个回答
3
投票

您可以使用

HashSet<T>
来执行类似的操作。

IEnumerable<T> OrderedDistinct<T>(IEnumerable<T> source)
{
    var set = new HashSet<T>();
    foreach (var item in source)
    {
        if (set.Add(item))
        {
            yield return item;
        }
    }
}

有趣的是,这正是Enumerable.Distict

所做的
,这意味着Distinct
将保留源中项目的顺序。但是,文档指出“结果序列是无序的”,这意味着他们将来可以自由地更改此行为。


0
投票
您可以在

Distinct

 上使用 
List<T>

numbers.Distinct();
但请注意,它不能保证保留顺序 - 尽管从当前的实现来看似乎是这样。他们将来改变实施的可能性是——尽管

非常低。

如果您需要这种保证,循环您的列表并记住这些项目对我来说似乎很好:

var result = new List<T>(); var uniques = new HashSet<T>(); foreach(var e in myList) if(uniques.Add(e) { result.Add(e); }
请注意,我使用 

HashSet

 仅用于 
检查 元素是否已在结果集中,而不依赖于其顺序。

© www.soinside.com 2019 - 2024. All rights reserved.