2009-09-26 13 views
21

में आइटम को हटाते समय मेरे पास सी # में हैशसेट है कि अगर मैं हैशसेट के बावजूद एक शर्त पूरी हो जाती है और नीचे दिए गए फ़ोरैच लूप का उपयोग करके ऐसा नहीं कर पा रहा हूं तो मैं हटा रहा हूं।हैशसेट इटरेटिंग सी #

foreach (String hashVal in hashset) 
{ 
    if (hashVal == "somestring") 
    { 
      hash.Remove("somestring"); 
    } 
} 

तो, मैं पुनरावृत्त करते समय तत्वों को कैसे हटा सकता हूं?

उत्तर

44

उपयोग बजाय HashSet की RemoveWhere विधि:

hashset.RemoveWhere(s => s == "somestring"); 

आप को पैरामीटर के रूप में एक शर्त/विधेय निर्दिष्ट प्रक्रिया। भविष्यवाणी से मेल खाने वाले हैशसेट में कोई भी आइटम हटा दिया जाएगा।

यह हैशसेट को संशोधित करने की समस्या से बचाता है, जबकि इसे फिर से चालू किया जा रहा है।


अपनी टिप्पणी के जवाब में:

'एस' वर्तमान आइटम का प्रतिनिधित्व करता है HashSet के भीतर से मूल्यांकन किया जा रहा।

hashset.RemoveWhere(delegate(string s) {return s == "somestring";}); 

या:

hashset.RemoveWhere(ShouldRemove); 

public bool ShouldRemove(string s) 
{ 
    return s == "somestring"; 
} 

संपादित करें: कुछ सिर्फ मेरे लिए हो गई है: के बाद से HashSet एक सेट है कि कोई भी शामिल

ऊपर कोड के बराबर है डुप्लिकेट मान, बस hashset.Remove("somestring") पर कॉल करना पर्याप्त होगा। लूप में ऐसा करने की कोई आवश्यकता नहीं है क्योंकि कभी भी एक मैच से अधिक नहीं होगा।

+0

धन्यवाद क्या प्रतिनिधित्व करेगा? – aHunter

+0

'हैशसेट के मूल्यांकन से वर्तमान आइटम का प्रतिनिधित्व करता है। अद्यतन उत्तर देखें। – adrianbanks

1

आमतौर पर जब मैं कुछ अधिक पुनरावृति और मूल्यों निकालना चाहते हैं मैं का उपयोग करें:

For (index = last to first) 
     If(ShouldRemove(index)) Then 
      Remove(index) 
+0

धन्यवाद मुझे पता है कि मैं लूप के लिए उपयोग कर सकता हूं, आप इस तरह से इंडेक्स स्थिति का उपयोग करके हैशसेट तक नहीं पहुंच सकते हैं। अगर मैं सी ++ का उपयोग कर रहा था तो मैं बस पॉइंटर्स का उपयोग करता हूं, मैं इसे सी # में नहीं कर सकता। – aHunter

+0

यदि संभव हो तो आप एक अलग डेटा संरचना का उपयोग करने पर भी विचार कर सकते हैं। – Nescio

8

आप एक संग्रह से वस्तुओं को हटा नहीं सकते हैं जबकि एक गणनाकर्ता के साथ इसे लूपिंग करते हैं। इस को हल करने के दो तरीके हैं:

  • लूप पीछे की ओर संग्रह का उपयोग करने पर एक नियमित रूप से अनुक्रमित के लिए लूप (जो मेरा मानना ​​है कि एक HashSet के मामले में एक विकल्प नहीं है) संग्रह से अधिक
  • लूप, जोड़ने के आइटम एक और संग्रह, फिर "होने वाली नष्ट कर दिया" -collection से अधिक पाश को हटा दिया और हटाने जा करने के लिए आइटम:

दूसरा दृष्टिकोण का उदाहरण:

HashSet<string> hashSet = new HashSet<string>(); 
hashSet.Add("one"); 
hashSet.Add("two"); 

List<string> itemsToRemove = new List<string>(); 
foreach (var item in hashSet) 
{ 
    if (item == "one") 
    { 
     itemsToRemove.Add(item); 
    } 
} 

foreach (var item in itemsToRemove) 
{ 
    hashSet.Remove(item); 
} 
+0

कार्यक्रम पहले से ही काफी गहन गहन है इसलिए मैं दूसरी सूची का उपयोग नहीं करूंगा। धन्यवाद – aHunter

+0

मैं दो foreach पाश का उपयोग करने से बचना होगा - एक foreach पाश पर्याप्त है, मेरा जवाब देखें – javapowered

4

मैं दो foreach पाश का उपयोग कर से बचने के हैं - एक foreach पाश पर्याप्त है:

HashSet<string> anotherHashSet = new HashSet<string>(); 
foreach (var item in hashSet) 
{ 
    if (!shouldBeRemoved) 
    { 
     anotherSet.Add(item); 
    } 
} 
hashSet = anotherHashSet; 
0

हालांकि मैं यह व्यक्तिगत रूप से पसंद नहीं है आप कुंजी में मान के रूप में एक HashSet के बजाय एक OrderedDictionary का उपयोग कर और nulls जोड़कर इस समस्या को हल कर सकते हैं/मूल्य जोड़ों। यह आपको लूप का उपयोग करके इंडेक्स द्वारा आइटम्स के माध्यम से लूप करने की अनुमति देगा।

OrderedDictionary d = new OrderedDictionary; 
//Code to fill it up 
for (int i = 0;i < d.Count;i++) 
    if (shouldRemove(d[i])) 
     d.RemoveAt(i); 

नोट वहाँ तथ्य यह है कि यह यह असंभव मामले में जहां कुंजी पूर्णांक हैं में सूचकांक द्वारा या आइटम द्वारा तक पहुँचने के बीच अंतर करना होगा की वजह से OrderedDictionary उपलब्ध का कोई जेनेरिक वर्जन है कि अन्य डेटा प्रकार के विपरीत है। इससे बहुत सारे कास्टिंग और टाइपिंग जांच हो सकती है, इसलिए उपर्युक्त समाधान विकल्प नहीं हैं, तो केवल इसका उपयोग करें।

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