99

我有一个小字节列表,我想测试它们是否都是不同的值。例如,我有这个:

List<byte> theList = new List<byte> { 1,4,3,6,1 };

检查所有值是否不同的最佳方法是什么?

4

8 回答 8

189
bool isUnique = theList.Distinct().Count() == theList.Count();
于 2013-08-18T21:36:55.217 回答
83

这是另一种比Enumerable.Distinct+更有效的方法Enumerable.Count(如果序列不是集合类型,则更有效)。它使用HashSet<T>消除重复的 a ,在查找中非常有效并且具有计数属性:

var distinctBytes = new HashSet<byte>(theList);
bool allDifferent = distinctBytes.Count == theList.Count;

或另一种更微妙和更有效的方法:

var diffChecker = new HashSet<byte>();
bool allDifferent = theList.All(diffChecker.Add);

HashSet<T>.Add如果false元素已经在HashSet. Enumerable.All停在第一个“假”上。

于 2013-08-18T21:59:43.880 回答
10

好的,这是我能想到的使用标准 .Net 的最有效方法

using System;
using System.Collections.Generic;

public static class Extension
{
    public static bool HasDuplicate<T>(
        this IEnumerable<T> source,
        out T firstDuplicate)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }

        var checkBuffer = new HashSet<T>();
        foreach (var t in source)
        {
            if (checkBuffer.Add(t))
            {
                continue;
            }

            firstDuplicate = t;
            return true;
        }

        firstDuplicate = default(T);
        return false;
    }
}

本质上,如果您只想找到第一个重复项,那么枚举整个序列两次的意义何在。

我可以通过特殊封装一个空的和单个元素的序列来优化它,但这会以最小的增益降低可读性/可维护性。

于 2017-02-02T11:59:00.060 回答
3

Distinct与使用类似的逻辑GroupBy

var isUnique = theList.GroupBy(i => i).Count() == theList.Count;
于 2019-09-12T22:37:18.153 回答
1

也可以这样做:使用 Hashset

var uniqueIds = new HashSet<long>(originalList.Select(item => item.Id));

            if (uniqueIds.Count != originalList.Count)
            {
            }
于 2020-04-14T10:20:03.497 回答
0

有很多解决方案。

毫无疑问,正如“juergen d”和“Tim Schmelter”提到的那样,使用 LINQ 会更漂亮。

但是,如果你裸露“复杂性”和速度,最好的解决方案就是自己实现它。解决方案之一是创建一个 N 大小的数组(字节为 256)。并循环数组,并且在每次迭代中,如果值为 1,则测试匹配的数字索引,这意味着我已经增加了数组索引,因此数组不是不同的,否则我将增加数组单元格并继续检查.

于 2013-08-18T21:41:55.573 回答
0

还有另一个解决方案,如果你想找到重复的值。

var values = new [] { 9, 7, 2, 6, 7, 3, 8, 2 };

var sorted = values.ToList();
sorted.Sort();
for (var index = 1; index < sorted.Count; index++)
{
    var previous = sorted[index - 1];
    var current = sorted[index];
    if (current == previous)
        Console.WriteLine(string.Format("duplicated value: {0}", current));
}

输出:

duplicated value: 2
duplicated value: 7

http://rextester.com/SIDG48202

于 2017-02-02T09:04:45.373 回答
0

我检查一个 IEnumerable (aray, list, etc) 是否像这样是唯一的:

var isUnique = someObjectsEnum.GroupBy(o => o.SomeProperty).Max(g => g.Count()) == 1;
于 2020-07-17T13:10:20.677 回答