2010-03-22 8 views
8

मेरे पास 3 (संपादित करें) पारस्परिक रूप से अनन्य IENumerables जिन्हें मैं फिर से चालू करना चाहता हूं।IENumerables के संग्रह पर पूर्वानुमान

IEnumerable<Car> redCars = GetRedCars(); 
IEnumerable<Car> greenCars = GetGreenCars(); 
IEnumerable<Car> blueCars = GetBlueCars(); 

foreach(Car c in (redCars + greenCars + blueCars)) { 
    c.DoSomething(); 
} 

... 

सबसे अच्छा तरीका है मैं है के बारे में सोच सकते हैं::

... 
List<Car> allCars = new List(); 
allCars.AddRange(redCars); 
allCars.AddRange(greenCars); 
allCars.AddRange(blueCars); 
foreach(car in allCars) { 
    ... 
} 
... 

वहाँ यह करने के लिए अधिक संक्षिप्त तरीका है मैं कुछ इस तरह करना चाहते हैं? ऐसा लगता है कि Inumberables को जोड़ना तुच्छ होना चाहिए।

उत्तर

20
LINQ के साथ

:

foreach(car in redCars.Concat(greenCars).Concat(blueCars)) { 
    //... 
} 

जानकारी के लिए, Union और Concat के बीच का अंतर है कि यहाँ Union अतिरिक्त काम विशिष्टता की गारंटी करने के क्या करेंगे है; इसलिए यदि आप डुप्लिकेट की अपेक्षा नहीं करते हैं (या वैकल्पिक रूप से: उन्हें ध्यान न दें) तो Concat तेज है।

+2

हे ... मैंने कंसट से शुरुआत की और फिर संघ गया और फिर फैसला किया कि मैं तय नहीं कर सकता कि किस का उपयोग करना है, इसलिए मैंने अपना जवाब हटा दिया। मैं वैसे भी अंतर को बेहतर तरीके से समझाता हूं। +1 – Randolpho

+0

बिल्कुल वही जो मैं खोज रहा था। धन्यवाद! – sdr

+0

@sdr: ध्यान दें कि यहां एक समय/स्थान व्यापार है। मान लीजिए कि आपके पास दस हजार तत्वों के साथ तीन लेकिन बीस ऐसी सूचियां नहीं थीं। आपकी विधि (उन्हें सभी को एक बड़ी सूची में एक साथ जोड़ना) लगभग 20 x 10K अतिरिक्त संदर्भ लेता है और 20 x 10K संदर्भ प्रति संचालन लेता है। दूसरी तरफ, 20 बेवकूफ कॉन्सट्स करना, शून्य अतिरिक्त संदर्भ लेता है, लेकिन नेस्टेड कॉन्सट्स में घोंसले की गहराई के आधार पर एक प्रतिलिपि बोझ होता है, इसलिए 10 x 11 x 10K = 110K प्रतियां, 20K प्रतियां नहीं होंगी। विवरण के लिए http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx देखें। –

0

LINQ संघ विधि का उपयोग करें।

foreach(Car c in redCars.Union(greenCars).Union(blueCars)) 
{ 
    c.DoSomething(); 
} 
+0

यदि आपको इसे एक लूप में करने की ज़रूरत है, तो मैं LINQ के साथ जाऊंगा। –

+0

उस बारे में नहीं सोचा था। लेकिन क्या यह निष्पक्ष नहीं होगा क्योंकि इसे उन सभी की तुलना करना है? विशेष रूप से क्योंकि तीन समूह परस्पर अनन्य हैं। – sdr

+1

जानकारी के लिए, 'संघ' अधिक महंगा होगा कि 'कंसट' यहां, और 'एड्रेंज' दृष्टिकोण (जो अनिवार्य रूप से 'कंसैट' है) के लिए एक अलग परिणाम का उत्पादन कर सकता है। –

0

क्या कोई कारण है कि आपको इसे एक लूप में करने की आवश्यकता है? यदि ऐसा है, तो दूसरा तरीका शायद सबसे अच्छा है। ऐसा कुछ भी नहीं है जो पहले तरीके से काम करेगा।

जब तक एक लूप में इसे ओवरराइड करने की आवश्यकता नहीं होती है, तो मैं इसे तीन लूप में करूँगा जो अधिक समय प्रभावी होगा।

+1

मुझे लगता है कि "अधिक समय कुशल" एक बड़ा दावा है। ध्यान दें कि एक सूची बनाना (आवंटन, प्रतिलिपि, आदि) के साथ एक ओवरहेड भी है। और वहां बहुत कुछ * है * ऐसा कुछ है जो पहले तरीके से काम करेगा। –

+0

@ स्कॉट, अगर वह प्रत्येक कार के साथ काम कर रहा है, तो वह एक से अधिक लूप क्यों चाहेंगे? यह सिर्फ अनावश्यक कोड है। –

3

जैसा कि अन्य उत्तरों में उल्लेख किया गया है, यूनियन डुप्लिकेट को खत्म करने के लिए अतिरिक्त काम करता है, कंसट बस अनुक्रमों को जोड़ता है। हालांकि, जैसा कि मैंने उपर्युक्त टिप्पणी में उल्लेख किया है, वहां घनिष्ठ घोंसले के लिए प्रदर्शन लागतें हैं। तुम भी iterators का एक समूह समतल करने के लिए एक SelectMany उपयोग करने पर विचार हो सकता है:

var carLists = new[]{GetRedCars(), GetGreenCars(), GetBlueCars()}; 
var allCars = from carList in carLists 
       from car in carList 
       select car; 
foreach(var c in allCars) { ... } 

आप आपको लगता है कि आप वास्तव में पुनरावृति करने के लिए रास्ता तीन से अधिक सूचियां की खोज करना चाहिए अधिक लचीला होना है कि मिल सकती है।

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