Lambda从列表<>中删除重复值的最快方法


73

从列表中删除重复值的最快方法是什么。假设List<long> longs = new List<long> { 1, 2, 3, 4, 3, 2, 5 };因此我在使用lambda删除重复并返回时很有趣:{1, 2, 3, 4, 5}。你有什么建议?


5
怎么样longs.Distinct()
zerkms,2012年

Answers:


131

获取列表的最简单方法是:

List<long> unique = longs.Distinct().ToList();

这对您来说足够好了吗,还是您需要更改现有列表?后者的作用要大得多。

请注意,Distinct()不能保证保留原始顺序,但是在当前实现中,它将保留-这是最自然的实现。有关更多信息,请参见我的Edulinq博客文章Distinct()

如果您不需要将其设为List<long>,则可以将其保留为:

IEnumerable<long> unique = longs.Distinct();

此时,每次您进行迭代时,它将进行重复数据删除unique。这是否好取决于您的要求。


谢谢,所以我认为longs = longs.Distinct().ToList()是正确的。对?
赛义德(Saeid)

2
@Saeid:只要没有其他东西已经引用原始列表,那应该没问题。您需要区分突变列表本身和更改变量以引用新列表(该代码将执行此操作)。
乔恩·斯基特

如果重要的是更改相同的列表,我们不能只说:var newTmpList = longs.Distinct().ToList(); longs.Clear(); longs.AddRange(newTmpList);
Jeppe Stig Nielsen

1
@JeppeStigNielsen:是的,这是有可能的-但这并不是一种非常好的方法...
Jon Skeet 2012年

1
这对我有用。我的情况是,我需要更新列表,所以我做了以下工作: long = long.Distinct().ToList();
Tscott

83

您可以对包含更复杂类型的枚举使用此扩展方法:

IEnumerable<Foo> distinctList = sourceList.DistinctBy(x => x.FooName);

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector)
{
    var knownKeys = new HashSet<TKey>();
    return source.Where(element => knownKeys.Add(keySelector(element)));
}

6
+1出色的答案-所有涵盖的答案始终是我的最爱!这正是我想要的。我喜欢原始体和复杂类型之间总是存在差异。这几乎和学习一门新语言一样糟糕,仅拥有#(*%$()* @无用的世界示例!好吧,走开我的肥皂盒,好答案!
dyslexicanaboko 2012年

我也更喜欢此解决方案,因为它使用lambda作为标题中要求的OP(请注意:Linq的Distinct()不),因此可以轻松地将其用于其他数据类型,而无需实现Equals/GetHashCodeIEqualityComparer
ZoolWay

很优雅的解决方案,但之后呢?我们有一个sourceList和一个distinctList。我们如何更新dbSet以反映数据库上的更改?
NolmëINFORMATIQUE

很棒的答案!并且您想通过许多按键来区分,只需使用不同的按键选择器多次调用即可:)
Al-Hanash Moataz

7

有Distinct()方法。它应该工作。

List<long> longs = new List<long> { 1, 2, 3, 4, 3, 2, 5 };
var distinctList = longs.Distinct().ToList();

7

如果要坚持使用原始List而不是创建一个新List,则可以执行类似于Distinct()扩展方法在内部执行的操作的方法,即使用HashSet检查唯一性:

HashSet<long> set = new HashSet<long>(longs.Count);
longs.RemoveAll(x => !set.Add(x));

List类提供了这种方便的RemoveAll(predicate)方法,该方法删除所有不满足谓词指定条件的元素。谓词是使用列表元素类型的参数并返回布尔值的委托。HashSet的Add()方法仅在集合尚不包含该项的情况下才返回true。因此,通过从列表中删除所有无法添加到集合中的项目,可以有效地删除所有重复项。



2

简单直观的实现

public static List<PointF> RemoveDuplicates(List<PointF> listPoints)
{
    List<PointF> result = new List<PointF>();

    for (int i = 0; i < listPoints.Count; i++)
    {
        if (!result.Contains(listPoints[i]))
            result.Add(listPoints[i]);
    }

    return result;
}

-2

到位:

    public static void DistinctValues<T>(List<T> list)
    {
        list.Sort();

        int src = 0;
        int dst = 0;
        while (src < list.Count)
        {
            var val = list[src];
            list[dst] = val;

            ++dst;
            while (++src < list.Count && list[src].Equals(val)) ;
        }
        if (dst < list.Count)
        {
            list.RemoveRange(dst, list.Count - dst);
        }
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.