C# 测试列表中的所有值是否唯一

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18303897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:51:39  来源:igfitidea点击:

Test if all values in a list are unique

c#

提问by frenchie

I have a small list of bytes and I want to test that they're all different values. For instance, I have this:

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

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

What's the best way to check if all values are distinct or not?

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

采纳答案by juergen d

bool isUnique = theList.Distinct().Count() == theList.Count();

回答by Orel Eraki

There are many solutions.

有很多解决方案。

And no doubt more beautiful ones with the usage of LINQ as "juergen d" and "Tim Schmelter" mentioned.

毫无疑问,使用 LINQ 作为“juergen d”和“Tim Schmelter”提到的更漂亮。

But, if you bare "Complexity" and speed, the best solution will be to implement it by yourself. One of the solution will be, to create an array of N size (for byte it's 256). And loop the array, and on every iteration will test the matching number index if the value is 1 if it does, that means i already increment the array index and therefore the array isn't distinct otherwise i will increment the array cell and continue checking.

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

回答by Tim Schmelter

Here's another approach which is more efficient than Enumerable.Distinct+ Enumerable.Count(all the more if the sequence is not a collection type). It uses a HashSet<T>which eliminates duplicates, is very efficient in lookups and has a count-property:

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

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

or another - more subtle and efficient - approach:

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

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

HashSet<T>.Addreturns falseif the element could not be added since it was already in the HashSet. Enumerable.Allstops on the first "false".

HashSet<T>.Addfalse如果元素无法添加,则返回,因为它已经在HashSet. Enumerable.All在第一个“假”处停止。

回答by Kevin Struillou

And another solution, if you want to find duplicated values.

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

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));
}

Output:

输出:

duplicated value: 2
duplicated value: 7

http://rextester.com/SIDG48202

http://rextester.com/SIDG48202

回答by Jodrell

Okay, here is the most efficient method I can think of using standard .Net

好的,这是我能想到的使用标准 .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;
    }
}

essentially, what is the point of enumerating the whole sequence twice if all you want to do is find the first duplicate.

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

I could optimise this more by special casing an empty and single element sequences but that would depreciate from readability/maintainability with minimal gain.

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

回答by Vitali Kuzniatsou

The similar logic to Distinctusing GroupBy:

类似的逻辑来Distinct使用GroupBy

var isUnique = theList.GroupBy(i => i).Count() == theList.Count;

回答by Gauravsa

One can also do: Use Hashset

还可以这样做:使用 Hashset

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

            if (uniqueIds.Count != originalList.Count)
            {
            }