एक कस्टम क्लास लिस्ट <T> क्रमित करें


112

मैं अपनी सूची dateसंपत्ति के साथ क्रमबद्ध करना चाहूंगा ।

यह मेरी कस्टम क्लास है:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Test.Web
{
    public class cTag
    {
        public int id { get; set; }
        public int regnumber { get; set; }
        public string date { get; set; }
    }
}

यह एक ऐसा है Listजो मैं चाहता हूं:

List<cTag> Week = new List<cTag>();

मैं जो करना चाहता हूं date, वह सीटीजी वर्ग की संपत्ति द्वारा सूची को क्रमबद्ध करना है । प्रारूप में दिनांक ist: dd.MM.yyyy है।

मैं IComparableइंटरफ़ेस के बारे में कुछ पढ़ता हूं , लेकिन इसका उपयोग करना नहीं जानता।

जवाबों:


143

ऐसा करने का एक तरीका ए है delegate

List<cTag> week = new List<cTag>();
// add some stuff to the list
// now sort
week.Sort(delegate(cTag c1, cTag c2) { return c1.date.CompareTo(c2.date); });

98
आप एक ही बात को list.Sort((a,b) => a.date.CompareTo(b.date));
लंबोदर

2
@Xavier किसी कारण से मेरा मन अभी भी हमेशा पहले से भविष्यवाणी करने के लिए कूदता है, हालांकि आप 100% सही हैं कि आपकी लैम्ब्डा अभिव्यक्ति को काम मिल जाएगा और शायद पढ़ने / समझने में आसान है।
अहस्तक्षेप

यह कैसे करता है, या आप कैसे करेंगे, लंबोदर अभिव्यक्ति का उपयोग करके एक टाई को लगातार तोड़ते हैं? क्या होगा यदि a.date == b.date यहाँ? list.Sort ((a, b) => a.date.CompareTo (b.date)); जब पेजिंग ग्रिड और ये दोनों अलग-अलग पन्नों पर पड़ने के कारण यह समस्या पैदा करेंगे?
theEmirOfGroofunkistan

1
@ TheEmOfGroofunkistan जो सभी पर निर्भर करता है कि CompareToइसे कैसे लागू किया जाता है। IComparableअनुदान देता है कि एक वर्ग के पास विधि होगी लेकिन यह कैसे करता है कि तुलना कक्षा के निर्माता तक है। निश्चित नहीं है कि दिनांक ICompare को कैसे लागू करता है, लेकिन अक्सर मैंने देखा है कि डेवलपर्स मानों के बराबर होने पर टाई को तोड़ने के लिए ऑर्डर पैरामीटर का उपयोग करते हैं। hth
ahsteele

51

आप सही हैं कि आपके cTag वर्ग को IComparable<T>इंटरफ़ेस लागू करना चाहिए । तब आप बस Sort()अपनी सूची पर कॉल कर सकते हैं ।

IComparable<T>इंटरफ़ेस को लागू करने के लिए , आपको CompareTo(T other)विधि को लागू करना होगा । इसके लिए सबसे आसान तरीका यह है कि आप जिस क्षेत्र की तुलना करना चाहते हैं, उसकी तुलना विधि से करें।

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public string date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

हालाँकि, यह अच्छी तरह से सॉर्ट नहीं होगा, क्योंकि यह स्ट्रिंग्स पर क्लासिक सॉर्टिंग का उपयोग करेगा (क्योंकि आपने स्ट्रिंग के रूप में तारीख घोषित की है)। इसलिए मुझे लगता है कि ऐसा करने के लिए सबसे अच्छा होगा कि कक्षा को फिर से परिभाषित करना और तारीख को स्ट्रिंग के रूप में घोषित नहीं करना होगा, लेकिन डेटटाइम के रूप में। कोड लगभग समान रहेगा:

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public DateTime date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

अपनी स्ट्रिंग को डेटटाइम प्रकार में बदलने के लिए कक्षा का उदाहरण बनाते समय केवल आपको ही करना होगा, लेकिन इसे आसानी से किया जा सकता है DateTime.Parse(String)


38

इस मामले के लिए आप LINQ का उपयोग करके भी छाँट सकते हैं:

week = week.OrderBy(w => DateTime.Parse(w.date)).ToList();


9

पहले चीजें पहले, अगर डेट प्रॉपर्टी डेट को स्टोर कर रही है, तो डेटटाइम का उपयोग करके इसे स्टोर करें। यदि आप तारीख को उस प्रकार से पार करते हैं, जिसके लिए आपको प्रत्येक आइटम की तुलना करने के लिए उसे पार्स करना है, तो यह बहुत कुशल नहीं है ...

फिर आप एक IComparer बना सकते हैं:

public class TagComparer : IComparer<cTag>
{
    public int Compare(cTag first, cTag second)
    {
        if (first != null && second != null)
        {
            // We can compare both properties.
            return first.date.CompareTo(second.date);
        }

        if (first == null && second == null)
        {
            // We can't compare any properties, so they are essentially equal.
            return 0;
        }

        if (first != null)
        {
            // Only the first instance is not null, so prefer that.
            return -1;
        }

        // Only the second instance is not null, so prefer that.
        return 1;
    }
}

var list = new List<cTag>();
// populate list.

list.Sort(new TagComparer());

आप इसे एक प्रतिनिधि के रूप में भी कर सकते हैं:

list.Sort((first, second) =>
          {
              if (first != null && second != null)
                  return first.date.CompareTo(second.date);

              if (first == null && second == null)
                  return 0;

              if (first != null)
                  return -1;

              return 1;
          });

6

आप सही हैं - आपको IComparable को लागू करने की आवश्यकता है। ऐसा करने के लिए, बस अपनी कक्षा घोषित करें:

public MyClass : IComparable
{
  int IComparable.CompareTo(object obj)
  {
  }
}

तुलना में, आप बस अपने कस्टम तुलना एल्गोरिथ्म को लागू करते हैं (आप ऐसा करने के लिए डेटटाइम ऑब्जेक्ट्स का उपयोग कर सकते हैं, लेकिन बस "obj" के प्रकार की जांच करने के लिए निश्चित रहें)। अधिक जानकारी के लिए, यहां और यहां देखें ।


7
IComparable<T>संभवतः एक बेहतर विकल्प होगा, क्योंकि यह वरीयता के लिए जाँच की जाती है IComparable: msdn.microsoft.com/en-us/library/b0zbh7b6.aspx
रिचर्ड

5

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

var q = from tag in Week orderby Convert.ToDateTime(tag.date) select tag;
List<cTag> Sorted = q.ToList()

3

सूची वर्ग के अतिभारित क्रमबद्ध विधि को देखें। इसके कुछ तरीके हैं। उनमें से एक: आपके कस्टम वर्ग को IComparable इंटरफ़ेस लागू करना होता है तब आप सूची वर्ग के क्रमबद्ध तरीके का उपयोग करते हैं।


3

सभी तेज़ उत्तर के लिए धन्यवाद।

यह मेरा समाधान है:

Week.Sort(delegate(cTag c1, cTag c2) { return DateTime.Parse(c1.date).CompareTo(DateTime.Parse(c2.date)); });

धन्यवाद


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.