2010-10-06 16 views
6

मैं इस तरह एक संग्रह है में प्रकार के आधार पर,एक संग्रह LINQ

Class Base{} 
Class A : Base {} 
Class B : Base {} 

List<Base> collection = new List<Base>(); 
collection.Add(new A()); 
collection.Add(new B()); 
collection.Add(new A()); 
collection.Add(new A()); 
collection.Add(new B()); 

अब मैं प्रकार (ए/बी) पर आधारित संग्रह क्रमबद्ध करना चाहते हैं सॉर्ट करने के लिए कैसे। मैं यह कैसे कर सकता हूं? क्रिप्या मेरि सहायता करे।

उत्तर

7

आप प्रकार का उपयोग कर सकते हैं

वैकल्पिक रूप से, अगर आप इस तरह एक डाटा-संरचना में 'समूह' रख सकते हैं सूचना स्वयं:

collection.Sort((a,b) => 
    { 
     bool aType = a.GetType() == typeof(A); 
     bool bType = b.GetType() == typeof(A); 
     return aType.CompareTo(bType); 
    }); 

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

आप कई प्रकार का समर्थन करने की जरूरत है, और आदेश आप की तरह कुछ कर सकता है पहले से निर्दिष्ट करने की जरूरत नहीं है, तो: एक सी:

collection.Sort((a,b) => a.GetType().FullName.CompareTo(b.GetType().FullName)); 

यह प्रकार की कोई भी संख्या (यानी संभाल होगा और एक डी उप प्रकार भी), और उन्हें अपने पूर्ण प्रकार के नाम से आदेश दें।

+0

@ एंथनी: हाँ - यहां शून्य के लिए कोई जांच नहीं है। अभी, ए या बी के अलावा कुछ भी बी के रूप में माना जाएगा ... –

+0

हां, मैंने इसे एक और नजर डाला, और यह पता चला कि यह बिल्कुल * नहीं है * मैं टाइप के लिए लेखांकन नहीं करने के कारण दूर जाऊंगा * सी: बेस'। मैं संभवतः 'ए। गेट टाइप()। नाम। कॉम्पारे के लिए (बी। गेट टाइप()। नाम') (और जो भी शून्य जांच, उन्हें प्रासंगिक होना चाहिए)। लेकिन कौन जानता है, शायद केवल दो प्रकार हैं, और हो सकता है कि 'ए' वास्तव में 'फू' है और 'बी' वास्तव में 'बार' और 'फू' को 'बार' से पहले आना चाहिए। –

+0

@Anthony: वहाँ मूल प्रश्न में वास्तव में पर्याप्त नहीं जानकारी पूरी तरह से इस निर्धारित करने के लिए है - यह आप कैसे तरह होता है पर अधिक नियंत्रण देता, लेकिन यह पता है कि ओपी वास्तव में चाहता है ... –

0

संपादित करें: मैं इस बारे में सोच रहा है कि आप क्या चाहते:

आप 'जगह से बाहर' छंटाई और सूची फिर नियत कोई आपत्ति नहीं है, तो यह काम करना चाहिए:

collection = collection.GroupBy(item => item.GetType()) 
         .SelectMany(g => g) 
         .ToList(); 

या पर निर्भर करता है आपके जरूरतों, जैसे कुछ:

collection = collection.OrderBy(item => item.GetType().FullName) 
         .ToList(); 

उस में जगह होना चाहिए, तो एक कस्टम comparer लेखन और list.Sort शायद सबसे अच्छा विकल्प है।


समूह प्रकार से आइटम करने के लिए

, आप GroupBy उपयोग कर सकते हैं:

var groupedItems = collection.GroupBy(item => item.GetType()); 

यह आस्थगित निष्पादन का उपयोग करता है।

var itemsByTypeLookUp = collection.ToLookup(item => item.GetType()); 

foreach(A a in itemsByTypeLookUp[typeof(A)]) 
{ 
    ... 
} 

आप केवल एक निश्चित प्रकार के लिए देख रहे हैं:

var itemsOfTypeA = collection.OfType<A>(); 
+0

इस समूह उन्हें, लेकिन तरह doens't सूची ... –

+0

@ रीड Copsey: धन्यवाद, संपादित। – Ani

1

collection.Where(entry => entry is A).Concat(collection.Where(entry => entry is B)) 

तुम क्या आवश्यकता है करता है?

1

यह ऑर्डर करने जा रहा है ताकि A दूसरा और B दूसरा होगा।

var xx = list.OrderBy(x => x.GetType() == typeof(B)).ToList(); 

यह निम्न सांत्वना परियोजना की पुष्टि करता है:

class Program 
{ 
    public class X { } 
    public class A : X { } 
    public class B : X { } 
    static void Main() 
    { 
     List<X> list = new List<X>(); 
     list.Add(new B()); 
     list.Add(new A()); 
     list.Add(new B()); 
     list.Add(new A()); 
     list.Add(new A()); 

     // A.GetType() == typeof(B) will be "0" making the type A go first 
     // B.GetType() == typeof(B) will be "1" making the type B go last 
     var xx = list.OrderBy(x => x.GetType() == typeof(B)).ToList(); 

     Console.ReadLine(); 
    } 
} 

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

+0

क्या होगा यदि 'सी: बेस' टाइप करें? –

+0

@ एंथनी: उसे प्रत्येक प्रकार को 'तुलनाकर्ता' के साथ संभालना होगा। जब तक कि बेस क्लास में 'ऑर्डर' नामक कोई संपत्ति न हो और आप इस संपत्ति द्वारा ऑर्डर कर सकें। चूंकि उन्होंने केवल 'ए' और 'बी' कहा है, मेरा मानना ​​है कि यह उनके लिए सबसे छोटा समाधान है। – BrunoLM

+0

@ जोन हन्ना आदेश को संभालने का एक दिलचस्प तरीका प्रदान करता है, एक और फ़ंक्शन के साथ और आप जो भी इंडेक्स चाहते हैं उसे प्रदान कर सकते हैं। बेशक, उस समारोह को प्रत्येक नए प्रकार के साथ संशोधित करना होगा। या, आपके मामले में, आप 'x => x.GetType() नाम से ऑर्डर कर सकते हैं। नाम', जो सी से पहले बी को पहले रखेगा। बेशक, यह हो सकता है कि ए और बी वास्तव में ए और बी नहीं हैं और एक वर्णमाला क्रम काम नहीं करेगा। तो, हाँ, अधिक जानकारी को छोड़कर, यह कहना मुश्किल है कि उत्तर क्या उचित है। मैं केवल कक्षा सी को एक विचार के रूप में फेंक देता हूं। –

6
private static int OrderOnType(Base item) 
{ 
    if(item is A) 
    return 0; 
    if(item is B) 
    return 1; 
    return 2; 
} 

फिर से अपने पिकअप ले:

collection.OrderBy(OrderOnType) 

या

collection.Sort((x, y) => OrderOnType(x).CompareTo(OrderOnType(y))); 

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

4
collection.OrderBy(i => i.GetType() == typeof(A) ? 0 : 1); 

आप सभी A के साथ एक दृश्य देंगे तो सभी B रों

+0

क्या होगा यदि 'सी: बेस' टाइप करें? –

+0

@ एंथनी पेग्राम - फिर यह दृष्टिकोण काम नहीं करेगा। मुझे लगता है कि आप टाइप नाम पर ऑर्डर कर सकते हैं, लेकिन फिर अगर आप उस मामले में ए, सी, बी होने का आदेश चाहते थे तो क्या होगा? यदि यह विधि बहुत सरल है, तो प्रश्न को और विवरण जोड़े जाने की आवश्यकता है। – Lee

+0

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

0

कुछ इस तरह मेरे लिए काम करता है।

collection.OrderBy(p => p.GetType().Equals(typeof(B))).ThenBy(p => p.GetType().Equals(typeof(A))).ToList(); 

मेरे कोड:

class Employer; 
class Doctor : Employer 
class Administrator : Employer 
class Nurse : Employer 
List<Employer> collection = new List<Employer>(); 
collection.Add(new Doctor()); 
collection.Add(new Administrator()); 
collection.Add(new Doctor()); 
collection.Add(new Nurse()); 
collection.Add(new Administrator()); 
collection = collection.OrderBy(p => p.GetType().Equals(typeof(Nurse))).ThenBy(p => p.GetType().Equals(typeof(Doctor))).ThenBy(p => p.GetType().Equals(typeof(Administrator))).ToList();