2012-08-04 17 views
19

मेरे पास list<message> है जिसमें Guid और DateTime (साथ ही साथ अन्य गुण) के गुण शामिल हैं। मैं उस सूची में सभी वस्तुओं से छुटकारा पाना चाहता हूं जहां Guid और DateTime समान हैं (एक को छोड़कर)। वहाँ बार जब उन दो संपत्तियों की सूची में अन्य मदों के रूप में ही किया जाएगा होगा, लेकिन अन्य गुण अलग होगा, तो मैं बस .Distinct()सूची में दो गुणों से अलग चुनें

List<Message> messages = GetList(); 
//The list now contains many objects, it is ordered by the DateTime property 

messages = from p in messages.Distinct( what goes here?); 

उपयोग नहीं कर सकते यह है कि मैं क्या अभी है, लेकिन ऐसा लगता है जैसे वहाँ एक बेहतर तरीका

List<Message> messages = GetList(); 

for(int i = 0; i < messages.Count() - 1) //use Messages.Count() -1 because the last one has nothing after it to compare to 
{ 
    if(messages[i].id == messages[i+1}.id && messages[i].date == message[i+1].date) 
    { 
     messages.RemoveAt(i+1); 
    { 
    else 
    { 
     i++ 
    } 
} 
+1

http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property – Shyju

+0

धन्यवाद:

इस तरह आप इसका इस्तेमाल होता है। मुझे नहीं पता कि जब मैंने खोज की तो मुझे वह क्यों नहीं मिला। – user1304444

+0

मुझे खुशी है कि जॉन का जवाब आपके लिए काम करता है। सावधानी बरतने का एक नोट: आपकी "वर्तमान में प्रयुक्त विधि" संकलित नहीं होती है, और (संकलन त्रुटियों को ठीक करने के बाद) यह सभी मामलों में काम नहीं करेगी - आपके तत्वों के क्रम के आधार पर, आप अलग-अलग ** (गलत) ** परिणाम (आखिरकार, आप केवल एक दूसरे के साथ आसन्न तत्वों की तुलना कर रहे हैं)। – Adam

उत्तर

52

वस्तुओं के लिए LINQ निर्मित एक तरह से आसानी से इस कार्यक्षमता प्रदान नहीं करता है होना चाहिए, लेकिन MoreLINQ एक आसान DistinctBy विधि है:

messages = messages.DistinctBy(m => new { m.id, m.date }).ToList(); 
+0

मुझे लगता है कि MoreLINQ उपयोग करने के लिए स्वतंत्र है? मैं नहीं देखता कि पेज पर कहीं भी स्पष्ट रूप से लिखा गया है। – user1304444

+2

@ user1304444: यह एक ओपन सोर्स लाइब्रेरी है - पृष्ठ के बाईं ओर "अपाचे लाइसेंस 2.0" लिंक देखें। –

+3

इस प्रश्न को देखने वाले किसी और के लिए, ऊपर वर्णित लिंक श्याजू का एक बड़ा जवाब भी प्रतीत होता है। http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property – user1304444

2

इसके बारे में क्या?

var messages = messages 
       .GroupBy(m => m.id) 
       .GroupBy(m => m.date) 
       .Select(m => m.First()); 
+0

संकलित नहीं करता है ... याद रखें कि GroupBy 'IGrouping' देता है। – Adam

+0

यह दृष्टिकोण मान्य है यदि हैशसेट प्लेटफॉर्म पर उपलब्ध नहीं है जो आप सिल्वरलाइट की तरह विकसित कर रहे हैं .... – Thomas

11

जॉन स्कीट के DistinctBy निश्चित रूप से जाने का रास्ता है, लेकिन अगर आप अपने खुद के विस्तार विधि को परिभाषित करने में रुचि रखते हैं तो आप इस अधिक संक्षिप्त संस्करण में फैंसी लग सकता है:

public static IEnumerable<TSource> DistinctBy<TSource, TKey> 
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) 
{ 
    var known = new HashSet<TKey>(); 
    return source.Where(element => known.Add(keySelector(element))); 
} 

जो एक ही हस्ताक्षर है :

messages = messages.DistinctBy(x => new { x.id, x.date }).ToList(); 
+2

मुझे पता है कि यह पुराना है, लेकिन कृपया ध्यान दें कि आपको 'DistinctBy()' को कॉल करने के बाद 'ToList() 'या' ToArray() 'को कॉल करना होगा। यदि आप सीधे 'आईन्यूमेरेबल' पर काम करते हैं और इसे कई बार गिनते हैं तो यह काम नहीं करेगा, क्योंकि पहली बार 'आईन्यूमेरेबल' के माध्यम से आइटम को 'हैशसेट' में जोड़ा जाता है और दूसरी बार वापस नहीं किया जाएगा, जैसा कि इस [.NET Fiddle] में दिखाया गया है (https://dotnetfiddle.net/5PUJxl)। – fknx

1

आप मेरी PowerfulExtensions लाइब्रेरी देख सकते हैं। वर्तमान में यह एक बहुत ही युवा चरण में है, लेकिन पहले से ही आप अलग-अलग गुणों को छोड़कर अलग, संघ, अंतर, विधियों का उपयोग कर सकते हैं;

using PowerfulExtensions.Linq; 
... 
var distinct = myArray.Distinct(x => x.A, x => x.B);