我有一小部分字节,我想测试一下它们是否都是不同的值。例如,我有这个:
List<byte> theList = new List<byte> { 1,4,3,6,1 };
检查所有值是否不同的最佳方法是什么?
Answers:
这是另一种比Enumerable.Distinct+更有效的方法Enumerable.Count(如果序列不是集合类型,则更为有效)。它使用aHashSet<T>来消除重复项,在查找中非常有效并且具有计数属性:
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停在第一个“假”上。
Assert.IsTrue(samples.Add(AwesomeClass.GetUnique()));。他们曾经是,现在是:)为您+1蒂姆:)
bool allDifferent = theList.All(s => diffChecker.Add(s))
List.All(HashSet.Add)在几乎所有情况下,第三个场景()似乎都比其他两个场景快得多
好的,这是我可以想到的使用标准.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;
}
}
本质上,如果您要做的就是找到第一个重复序列,那么将整个序列两次枚举的意义是什么。
我可以通过用特殊的空格和单个元素序列来进一步优化此效果,但这会以最小的增益降低可读性/可维护性。
sequence应该是source)。但是,一旦修复这些问题,效果就会很好
if (!checkBuffer.Add(t)) { firstDuplicate = t; return true }在循环中。
有很多解决方案。
毫无疑问,使用LINQ作为“ juergen d”和“ Tim Schmelter”使用的更漂亮。
但是,如果您没有“复杂性”和速度,那么最好的解决方案就是自行实现。解决方案之一是创建一个N大小的数组(字节为256)。然后循环数组,并且每次迭代都会测试匹配的数字索引(如果值是1的话),这意味着我已经增加了数组索引,因此数组没有区别,否则我将增加数组单元格并继续检查。
还有另一个解决方案,如果您要查找重复的值。
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
我检查IEnumerable(aray,list等)是否唯一,如下所示:
var isUnique = someObjectsEnum.GroupBy(o => o.SomeProperty).Max(g => g.Count()) == 1;