73

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

4

7 回答 7

133

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

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

这对你来说足够好,还是你需要改变现有的列表?后者明显更啰嗦。

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

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

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

此时,它会在您每次迭代时进行重复数据删除unique。好不好就看你的要求了。

于 2012-05-17T09:14:10.810 回答
84

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

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)));
}
于 2012-11-05T12:02:12.593 回答
7

有 Distinct() 方法。它应该有效。

List<long> longs = new List<long> { 1, 2, 3, 4, 3, 2, 5 };
var distinctList = longs.Distinct().ToList();
于 2012-05-17T09:14:09.400 回答
7

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

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

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

于 2012-05-27T08:55:46.753 回答
2
List<long> distinctlongs = longs.Distinct().OrderBy(x => x).ToList();
于 2012-05-17T09:14:19.600 回答
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;
}
于 2018-04-19T09:12:25.113 回答
-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);
        }
    }
于 2016-11-28T14:53:22.963 回答