2009-03-10 16 views
31

क्या लिनक विधि की एक चीज है जिसका उपयोग मैं यह जानने के लिए कर सकता हूं कि दो अनुक्रमों में एक ही आइटम है, खाते में ऑर्डर नहीं ले रहा है?सी #: दो आईनेमरेबल्स की सामग्री की तुलना करें

उदाहरण के लिए:

{1, 2, 3} == {2, 1, 3} 
{1, 2, 3} != {2, 1, 3, 4} 
{1, 2, 3} != {1, 2, 4} 

आप SequenceEquals है, लेकिन उसके बाद मैं पहली बार दोनों दृश्यों आदेश करने के लिए होता है, मैं नहीं है?

+0

संभावित डुप्लिकेट [उनमें से वस्तुओं के क्रम के बावजूद समानता के लिए दो संग्रहों की तुलना करना] (http://stackoverflow.com/questions/50098/comparing-two-collections-for-equality-irrespective-of-the- ऑर्डर-ऑफ-आइटम-इन-द) – nawfal

उत्तर

31

कुछ तरीके हैं। मान लें कि ए और बी आईनेमरेबल है।

!A.Except(B).Any() && !B.Except(A).Any() 
A.Count() == B.Count() && A.Intersect(B).Count() == B.Count() 
etc 
+0

इंटरसेक्ट का उपयोग करके, क्या आपको इसे दोनों तरीकों से करने की आवश्यकता है? – Svish

+0

मुझे लगता है कि अनुक्रमों को आदेश देने से यह बहुत धीमा है। जब तक आप अभिव्यक्ति पेड़ों से निपट नहीं रहे हैं। –

+0

@ स्विस: हाँ, आप * करते हैं * इसे दोनों तरीकों से करने की आवश्यकता है ए = बी iff ए Δ बी = Φ। –

1

मुझे लगता है कि अनुक्रम का क्रम सबसे तेज़ तरीका है जिसे आप प्राप्त कर सकते हैं।

+0

अनुक्रम के लिए यह एक ही क्रम होना है। – leppie

+0

"अनुक्रम Iqual <(<(TSource>)>) (IENumerable <(<(TSource>)>), IENumerable <(<(TSource>)>)) विधि दो स्रोत अनुक्रमों को समांतर में समझाती है और टीएसओआरएस के लिए डिफ़ॉल्ट समानता तुलनाकर्ता का उपयोग करके संबंधित तत्वों की तुलना करती है , चूक।" – Svish

+0

हाँ, मैंने सवाल को गलत तरीके से पढ़ा। यह ओ (nlogn) है जो इस उद्देश्य के लिए एक एल्गोरिदम प्राप्त कर सकते हैं सबसे तेज़ एसिम्प्टोटिक समय है। –

1

मैं डुप्लिकेट के बिना एक संग्रह में नए आइटम मर्ज करने के लिए ऐसा किया, यह दो संग्रह लेता है और हटाने के द्वारा अब डुप्लीकेट

List<Campaign> nonMatching = (from n in newCampaigns 
where !(from e in Existing select e.Id).Contains<int>(n.Id) 
select n).ToList<Campaign>(); 

बाहर के साथ सभी वस्तुओं रिटर्न! बयान के लिए

List<Campaign> nonMatching = (from n in newCampaigns 
where (from e in Existing select e.Id).Contains<int>(n.Id) 
select n).ToList<Campaign>(); 

यह आप वास्तव में सिर्फ अगर वहाँ डुप्लिकेट हैं देखने के लिए परीक्षण कर रहे हैं डुप्लिकेट

0

वापस आ जाएगी, तो leppie के सुझाव काम करना चाहिए:

if (A.Except(B).Count == 0 && B.Except(A).Count == 0) {...} 

लेकिन अगर आप केवल एक डुप्लिकेट के साथ एक आईनेमरेबल पर पहुंचने की आवश्यकता है:

var result = A.Union(B).Distinct(); 
3

हैशसेट सी आज़माएं lass:

var enumA = new[] { 1, 2, 3, 4 }; 
var enumB = new[] { 4, 3, 1, 2 }; 

var hashSet = new HashSet<int>(enumA); 
hashSet.SymmetricExceptWith(enumB); 
Console.WriteLine(hashSet.Count == 0); //true => equal 

लेकिन यह मान केवल अलग-अलग काम करता है यदि मान अलग हैं।

उदाहरण

var enumA = new[] { 1, 1, 1, 2 }; 
var enumB = new[] { 1, 2, 2, 2 }; 

के लिए भी रूप में उल्लेख किया विधि के साथ "बराबर" माना जाता है।

bool equal = (A.Count() == B.Count() && (!A.Except(B).Any() || !B.Except(A).Any())) 

मुझे लगता है कि इस को छोड़कर (ए) .Count क्योंकि पूरे EXCEP मूल्यांकन नहीं किया जाएगा से बेहतर है:

+1

'रिटर्न हैशसेट .etEquals (enumB);' – Spook

8
दो IEnumerables (ए और बी) के साथ

। जैसे ही एक तत्व को छोड़कर इसे छोड़ दिया जाएगा। गणना के साथ, संपूर्ण बहिष्कार का मूल्यांकन किया जाता है। इस के शीर्ष पर, हम केवल महंगी गुणों की जांच करके इन महंगी मूल्यांकनों से बच सकते हैं। यदि गणना समान नहीं हैं, तो हम छूट की जांच करते हैं।

+0

प्यार जो कि छोड़कर पहले विसंगति पर पैदा होगा - अच्छा! – U007D

2

आप डुप्लिकेट के बारे में परवाह नहीं करते हैं (अर्थात आप मानेंगे {1, 2, 3}{1, 2, 3, 2} के बराबर होना चाहिए) तो:

new HashSet<int>(A).SetEquals(B) 

(या जो कुछ भी है प्रकार तत्व int के बजाय टाइप)।

अन्यथा:

public static bool SequenceEqualUnordered<T>(IEnumerable<T> first, IEnumerable<T> second) 
{ 
    if (first == null) 
     return second == null; // or throw if that's more appropriate to your use. 
    if (second == null) 
     return false; // likewise. 
    var dict = new Dictionary<T, int>(); // You could provide a IEqualityComparer<T> here if desired. 
    foreach(T element in first) 
    { 
     int count; 
     dict.TryGetValue(element, out count); 
     dict[element] = count + 1; 
    } 
    foreach(T element in second) 
    { 
     int count; 
     if (!dict.TryGetValue(element, out count)) 
      return false; 
     else if (--count == 0) 
      dict.Remove(element); 
     else 
      dict[element] = count; 
    } 
    return dict.Count == 0; 
} 

पहले क्रम में प्रत्येक तत्व का एक मिलान करते रहें, फिर इसके खिलाफ दूसरे की जाँच करें। जिस क्षण आपके पास दूसरे अनुक्रम में बहुत अधिक है, आप झूठी वापसी कर सकते हैं, अन्यथा यदि आपके पास लम्बे समय के शब्दकोश में कुछ भी नहीं बचा है, तो वे बराबर हैं, या झूठ हैं यदि कोई तत्व शेष है।

OrderBy() का उपयोग करने के दो ओ (एन लॉग एन) प्रकारों के बजाय ओ (एन) तुलना के बाद, आपके पास ओ (एन) ऑपरेशन बिल्डिंग लम्बी सेट का सेट है, और ओ (एन) के खिलाफ जांच यह।

संबंधित मुद्दे