2011-02-23 15 views
23

मैं आईडी (पूर्णांक) की एक बहुत ही लंबी सूची है कि सभी वस्तुओं है कि मेरे डेटाबेस में वर्तमान में कर रहे हैं का प्रतिनिधित्व करता है में एक-दूसरे विशाल सूची घटाना कैसे करें:कुशलतापूर्वक सी #

var idList = GetAllIds(); 

मैं भी एक और विशाल सामान्य है आइटम के साथ सूची डेटाबेस में जोड़ने के लिए:

List<T> itemsToAdd; 

अब, मैं सामान्य सूची जिसका आईडी पहले idList में है के सभी आइटम हट करना चाहते हैं। वर्तमान में idList एक सरल सरणी है और मैं इस तरह सूचियों घटाना:

itemsToAdd.RemoveAll(e => idList.Contains(e.Id)); 

मैं बहुत यकीन है कि यह बहुत तेजी से हो सकता है कर रहा हूँ, इसलिए मैं दोनों संग्रहों के लिए क्या डेटाटाइप्स का उपयोग करना चाहिए और सबसे कुशल व्यवहार क्या है उन्हें घटाने के लिए?

धन्यवाद!

+0

मैं यह जानना चाहता हूं कि यदि संभव हो तो इसे स्ट्रीम/गणना कैसे करें ... – drzaus

उत्तर

17

अस्थायी रूप से एक HashSet<T> को idList रूपांतरण और एक ही विधि यानी उपयोग करें:

items.RemoveAll(e => idListHash.Contains(e.Id)); 

यह होना चाहिए बहुत तेजी से

+1

धन्यवाद - जो वास्तव में बहुत तेज़ करता है और मैंने जो किया है! – Shackles

2

आपको दो HashSet<int> एस का उपयोग करना चाहिए।
ध्यान दें कि वे अद्वितीय और अनियंत्रित हैं।

22

LINQ मदद कर सकता है:

itemsToAdd.Except(idList) 

आपका कोड धीमी है क्योंकि List<T>.ContainsO(n) है। तो आपकी कुल लागत O(itemsToAdd.Count*idList.Count) है।

आप idlist को HashSet<T> में बना सकते हैं जिसमें O(1).Contains है। या बस लिंक .Except एक्सटेंशन विधि का उपयोग करें जो आपके लिए करता है।

ध्यान दें कि .Except बाईं ओर से सभी डुप्लीकेट भी हटा देगा। यानी नया int[]{1,1,2}.Except(new int[]{2}) परिणामस्वरूप केवल {1} और दूसरा 1 हटा दिया गया था। लेकिन मुझे लगता है कि यह आपके मामले में कोई समस्या नहीं है क्योंकि आईडी आम तौर पर अद्वितीय होती हैं।

+0

ध्यान दें कि इससे 'आइटम्स टू एड' से किसी भी डुप्लीकेट को भी बाहर कर दिया जाएगा। चाहे यह एक समस्या है ओपी पर है या नहीं (मुझे संदेह नहीं है क्योंकि वे पहले से ही उनके उदाहरण में 'RemoveAll' का उपयोग कर रहे हैं)। – LukeH

+0

@LukeH मैं बस उसमें संपादन कर रहा था। – CodesInChaos

+0

+1 और उत्कृष्ट स्पष्टीकरण के लिए धन्यवाद! अब मैं हैशसेट के रूप में idList का निर्माण करता हूं लेकिन इसका उपयोग नहीं कर सकता। (क्योंकि) आइटम आइटम सूची प्रकार हैश/और idList प्रकार हैशसेट है। हालांकि यह बहुत तेज़ है और मेरी जरूरतों को पूरा करता है। – Shackles

5

मान लिया जाये कि निम्नलिखित परिसर सत्य हैं:

  • idList और itemsToAdd में डुप्लिकेट मान नहीं हो सकते हैं
  • आप .NET Framework 4 का उपयोग कर रहे हैं।(एन) आपरेशन,

    इस विधि एक हे है: 0

आप एक HashSet<T> इस तरह से इस्तेमाल कर सकते हैं:

var itemsToAddSet = new HashSet(itemsToAdd); 
itemsToAddSet.ExceptWith(idList); 

प्रलेखन के अनुसार ISet<T>.ExceptWith विधि बहुत कुशल है जहां n अन्य पैरामीटर में तत्वों की संख्या है।

आपके मामले में nidList में आइटमों की संख्या है।

+0

समस्या यह है कि आइटम ToAdd प्रकार हैशसेट और idList प्रकार हैशसेट है। इसलिए मैं इन दोनों के अलावा ExceptWith को कॉल नहीं कर सकता हूं और idList को हैशसेट में बदलने की आवश्यकता है जो बहुत सारी मेमोरी का उपभोग करेगी। – Shackles

+0

'idList' को 'हैशसेट ' नहीं होना चाहिए, आपको केवल 'आइटम्स टू एड' से बाहर हैशसेट बनाना होगा। इसके बाद आप 'idList' को 'हैशसेट ' एक्सेप्ट विथ 'को' IENumerable 'के रूप में पास कर देंगे। –

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