मेरे पास बाइट्स की एक छोटी सूची है और मैं परीक्षण करना चाहता हूं कि वे सभी अलग-अलग मूल्य हैं। उदाहरण के लिए, मेरे पास यह है:
List<byte> theList = new List<byte> { 1,4,3,6,1 };
यह जांचने का सबसे अच्छा तरीका है कि सभी मान अलग-अलग हैं या नहीं?
मेरे पास बाइट्स की एक छोटी सूची है और मैं परीक्षण करना चाहता हूं कि वे सभी अलग-अलग मूल्य हैं। उदाहरण के लिए, मेरे पास यह है:
List<byte> theList = new List<byte> { 1,4,3,6,1 };
यह जांचने का सबसे अच्छा तरीका है कि सभी मान अलग-अलग हैं या नहीं?
जवाबों:
bool isUnique = theList.Distinct().Count() == theList.Count();
यहां एक और दृष्टिकोण है जो Enumerable.Distinct+ से अधिक कुशल है Enumerable.Count(सभी अधिक अगर अनुक्रम संग्रह प्रकार नहीं है)। यह HashSet<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>.Addfalseयदि तत्व पहले से ही इसमें शामिल नहीं है तो रिटर्न देता है 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 }लूप में होना चाहिए ।
Distinctउपयोग करने के लिए समान तर्क GroupBy:
var isUnique = theList.GroupBy(i => i).Count() == theList.Count;
theList.GroupBy(o => o.SomeProperty).Count() == theList.Count;जबकि डिस्टिक्ट () इसकी अनुमति नहीं देता है।
कई उपाय हैं।
और LINQ के "juergen d" और "टिम श्मेल्टर" के रूप में उल्लेख के साथ और अधिक सुंदर लोगों पर कोई संदेह नहीं है।
लेकिन, यदि आप "जटिलता" और गति को नंगे करते हैं, तो सबसे अच्छा उपाय यह होगा कि आप इसे स्वयं लागू करें। समाधान में से एक होगा, एन आकार की एक सरणी बनाने के लिए (बाइट के लिए यह 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 (क्षय, सूची, आदि) इस तरह अद्वितीय है मैं जाँच करता हूँ:
var isUnique = someObjectsEnum.GroupBy(o => o.SomeProperty).Max(g => g.Count()) == 1;