当前位置: 首页 > 编程语言 > C#

找出IEnumerable是否具有唯一值的最佳方法分享

时间:2023-04-10 22:41:14 C#

找出IEnumerable是否具有唯一值的最佳方法我有很多代码可以用来做这样的事情boolGetIsUnique(IEnumerablevalues){返回值.Count()==values.Distinct().Count;有没有更好的方法来做到这一点?您的方法需要将序列迭代两次,但有一些潜在的缺点:对于任何显着大小的序列,迭代两次将比迭代一次慢。如果您尝试多次迭代某些序列,它们将抛出异常;其他人可能会为后续迭代返回不同的结果。您的方法使用Count,每次都需要迭代整个序列。一旦您知道存在重复值,就没有理由不提早爆破。以下方法仅迭代序列一次,并在遇到任何重复值时尽早中断:boolGetIsUnique(IEnumerablevalues){varset=newHashSet();foreach(Titeminvalues){if(!set.Add(item))returnfalse;}返回真;我会让这个不错的扩展方法publicstaticboolIsUnique(thisIEnumerablelist){varhs=newHashSet();返回list.All(hs.Add);}检查是否可以将所有项目添加到HashSet。我认为如果有非唯一值,这取决于你想做什么。@Jamiec或@LukeH的回答很好,可能最适合纯粹的速度,但它不会告诉您问题出在哪里。您也可以考虑类似vargroup=values.GroupBy(x=>x);返回group.Any(g=>g.Count()>1);这本质上比HashSet实现更糟糕。但是,如果保留此组,则可以找到重复的元素。vargroup=values.GroupBy(x=>x);返回group.Where(g=>g.Count()>1);或vargroup=values.GroupBy(x=>x);返回group.Where(g=>g.Count()>1).Select(g=>g.Key);通过GroupBy思考它可以让您为下一步做什么保持开放的选择。但是,如果您关心的是知道是否所有值都是唯一的,那么我会使用HashSet并且您将对上面的数据进行两次循环-一次获取计数,一次获取计数。如果前两项相同,尤其糟糕!尝试这样的事情:boolGetIsUnique(IEnumerablevalues){HashSethashSet=newHashSet();foreach(varvalueinvalues){if(hashSet.Contains(value)){returnfalse;}hashSet.Add(值);}返回真;一旦找到重复项,这一个就会完成。显然它与哈希查找的速度有关,但鉴于Distinct在内部使用集合,我仍然希望它更快。两条基本规则:最容易阅读和理解的方法几乎总是编写代码的最佳方法。这段代码很容易阅读,所以我说你可以开始了。性能(“更快”)应该只是一个问题,如果你能证明这是减慢你的程序的方式,或者如果你正在构建一个库,其他人在没有访问源代码的情况下无法访问。其他方法会更快(当发现重复值时它们会短路并返回false),但是,如果这是我的代码,我仍然会坚持使用您的版本。找到第一个重复项(如果存在)的快速方法是:publicstaticboolTryFindFirstDuplicate(thisIEnumerablesource,outTduplicate){varset=newHashSet();foreach(variteminsource){if(!set.Add(item)){duplicate=item;返回真;}}重复=默认(T);返回假;我很惊讶没有人测试过这个:将问题中的Gluip版本与JamieC、LukeK和MrKWatkins进行比较,这三个答案都优于提问者的版本。在这三个答案中,它们都具有相当的可比性,但在大多数情况下JamieC的答案稍快一些。当数据没有重复项或重复项位于IEnumerable的末尾时,大小或算法没有重大差异。当数据在中间或接近开始时有重复时,原始问题中的Gluip版本与其他三个版本相比表现较慢。检查集合的时间似乎与集合的大小成线性比例关系,这意味着没有针对大集合或小集合的最佳算法。这是一个显示CSV的测试程序,您可以将其加载到电子表格程序中,根据需要进行排序和绘图:测试程序:以上是找出IEnumerable是否具有唯一值的最佳方法如果方法共享的全部内容是对你有用,需要多了解C#学习教程,希望大家多多关注——usingSystem;使用System.Collections.Generic;使用系统诊断;使用System.IO;使用系统。林克;使用系统文本;使用System.Threading.Tasks;命名空间AreUniqueTest{类程序{constintIterations=1000;enumDupeLocation{None,Early,Center,Late,}enumSetSize{Tiny=10,Small=100,Medium=1000,Large=10000,Huge=100000,}staticvoidMain(){Dictionary,bool>>functions=newDictionary,bool>>{{"Gluip",GetIsUniqueGluip},{"LukeH",GetIsUniqueLukeH},{"Jamiec",GetIsUniqueJamiec},{"MrKWatkins",GetIsUniqueMrKWatkins}};varoutput=newStringBuilder();Console.WriteLine("函数,SetSize,DupeLocation,TotalTicks,AverageTicks");output.AppendLine("函数,SetSize,DupeLocation,TotalTicks,AverageTicks");foreach(Enum.GetValues中的SetSize大小(typeof(SetSize))){var大小值=(int)大小;foreach(DupeLocationlocationinEnum.GetValues(typeof(DupeLocation))){vardata=CreateTestData((int)size,location);foreach(stringfunctionKeyinfunctions.Keys){varticks=RunSet(functions[functionKey],data,Iterations);varavg=ticks/Iterations;Console.WriteLine($"{functionKey},{sizevalue},{location},{ticks},{avg}");output.AppendLine($"{functionKey},{sizevalue},{location},{ticks},{avg}");}}}File.WriteAllText("output.csv",output.ToString());Process.Start("输出.csv");}staticlongRunSet(Func,bool>getIsUnique,IEnumerablevalues,intiterations){varstopwatch=newStopwatch();秒表.Start();for(vari=0;i(IEnumerablevalues){varset=newHashSet();foreach(Titeminvalues){if(!set.Add(item))returnfalse;}returntrue;}staticboolGetIsUniqueGluip复制代码(IEnumerable值){returnvalues.Count()==values.Distinct().Count();}staticboolGetIsUniqueJamiec(IEnumerable列表){varhs=newHashSet();返回list.All(hs.Add);}staticboolGetIsUniqueMrKWatkins(IEnumerablevalues){HashSethashSet=newHashSet();foreach(varvalueinvalues){if(hashSet.Contains(value)){returnfalse;}hashSet.Add(值);}返回真;}staticint[]CreateTestData(intsize,DupeLocationlocation){varresult=newint[size];Parallel.For(0,size,i=>{result[i]=i;});返回SetDupe(结果,位置);}staticint[]SetDupe(int[]values,DupeLocationlocation){switch(location){caseDupeLocation.Early:values[1]=values[0];休息;caseDupeLocation.Center:varmidpoint=values.Length/2;值[中点]=值[中点+1];休息;caseDupeLocation.Late:values[values.Length-1]=values[values.Length-2];休息;//caseDupeLocation.None://什么都不做。}返回值;}}}本文收集自网络,不代表立场。如涉及侵权,请点击维权联系管理员删除,如有转载请注明出处: