Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 测试列表中的所有值是否唯一_C# - Fatal编程技术网

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

C# 测试列表中的所有值是否唯一,c#,C#,我有一个小的字节列表,我想测试它们是否都是不同的值。 例如,我有: List<byte> theList = new List<byte> { 1,4,3,6,1 }; List theList=新列表{1,4,3,6,1}; 检查所有值是否不同的最佳方法是什么?有很多解决方案 bool isUnique = theList.Distinct().Count() == theList.Count(); 毫无疑问,更漂亮的是使用了LINQ,如“juergen d”和“

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

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

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

有很多解决方案

bool isUnique = theList.Distinct().Count() == theList.Count();
毫无疑问,更漂亮的是使用了LINQ,如“juergen d”和“Tim Schmelter”所述

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

这里有另一种方法,它比
Enumerable.distinct
+
Enumerable.Count
(如果序列不是集合类型,则更有效)。它使用一个
哈希集
,该哈希集消除了重复项,在查找中非常有效,并且具有count属性:

var distinctBytes = new HashSet<byte>(theList);
bool allDifferent = distinctBytes.Count == theList.Count;
var distinctBytes=新哈希集(列表);
bool allDifferent=distinctBytes.Count==list.Count;
或者另一种更微妙、更有效的方法:

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

如果元素已在
哈希集中,因此无法添加,则返回
false
<代码>可枚举。所有
在第一个“false”处停止。

和另一个解决方案,如果要查找重复的值

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

好的,下面是我能想到的使用标准.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;
    }
}
使用系统;
使用System.Collections.Generic;
公共静态类扩展
{
公共静态布尔值(
这是一个数不清的来源,
输出(第一次重复)
{
if(source==null)
{
抛出新ArgumentNullException(nameof(source));
}
var checkBuffer=newhashset();
foreach(源中的var t)
{
if(checkBuffer.Add(t))
{
继续;
}
第一重复=t;
返回true;
}
firstDuplicate=默认值(T);
返回false;
}
}
从本质上讲,如果您只想找到第一个重复项,那么枚举整个序列两次有什么意义


我可以通过为空的单元素序列加上特殊的外壳来进一步优化这一点,但这会使可读性/可维护性降低,且收益最小。

使用
GroupBy
,类似于
Distinct

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

也可以这样做:使用Hashset

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

            if (uniqueIds.Count != originalList.Count)
            {
            }
var uniqueIds=newhashset(originalList.Select(item=>item.Id));
if(uniqueid.Count!=originalList.Count)
{
}
我检查IEnumerable(aray、list等)是否是唯一的,如下所示:

var isUnique = someObjectsEnum.GroupBy(o => o.SomeProperty).Max(g => g.Count()) == 1;

由于这是一个典型的教室问题,我将用一个问题来回答。如果它被分类,你会怎么做?只是好奇:这有什么空间和时间要求?@dtb。当然,考虑到这是一个“小列表”,几乎任何算法都会有闪电般的速度。在我看来,这在可读性和简洁性上是成功的,因为速度不是问题,这使它变得完美。这比使用256位=32字节=8整数的位向量更有效。但是你的大O=O(n)仍然与使用另一个答案中提出的哈希集相同。这是O(n),所以可能是最快的,(测试它)。在你走的时候检查计数还是在最后检查计数是最快的?我怀疑最终会改善最坏的情况,但随着时间的推移,可能会改善平均情况和最佳情况)。如果没有重复,这将是最糟糕的性能。同样,对于更大的数据类型,这也不能很好地工作,对于16位类型,您必须使用64k的计数,以及64k位(8k字节),但是对于任何更大的数据类型,内存使用将开始变得愚蠢。但是我喜欢这个8位值的答案。@TamusJRoyce如果你想存储4294967296种可能性,你需要4GB而不是42MB(或者512MB你使用位屏蔽),我不确定我在想什么。“分配42MB+的内存来容纳所有4294967296的可能性。并使用简单的桶计数器。甚至使用位屏蔽异或,检查是否有任何位从真变假。42MB+/8=5MB+对于今天的硬件来说,花费似乎太大了。但有一天这可能会有价值。”这不是一个真正相关的评论。哈希集最好。如果您处理的是非常大的数组,则需要非常大的内存。但在这种奇怪的边缘情况下,使用CRC算法的heristic会更好。将其映射到多项式。如果关闭,请进行评估。谢谢你@tigrou!这么简单和明显,为什么我不先考虑一下呢:)我在单元测试中使用了这个一行代码来确认我的优秀代码生成的1000万个元素是真正唯一的
Assert.IsTrue(samples.Add(AwesomeClass.GetUnique())。他们过去是,现在是:)+1给你蒂姆:)我试过你的答案,但不起作用先生:应该是这样:
bool allDifferent=theList.All=>diffChecker.Add(s))
No,不需要。在这种情况下,您可以传递委托directly@Andréreichlet-我刚刚打开了你的代码,第三个场景(
List.All(HashSet.Add)
)似乎比其他两个场景在几乎所有情况下都要快得多,只需添加一个重复的值输出返回,对于验证非常有用我在这里测试了3个解决方案,这确实是本页中最有效的。尽管有一些打字错误(例如
序列
应该是
源代码
)。但一旦这些都是fixed@mikenelson,这应该是更好的可读性,我认为它应该是
如果(!checkBuffer.Add(t)){firstDuplicate=t;return true}
在循环中。如果您想检查属性
的唯一性,这很有用
var isUnique = someObjectsEnum.GroupBy(o => o.SomeProperty).Max(g => g.Count()) == 1;