2008-11-14 18 views
83

List<> OrderBy Alphabetical Order के समान, हम एक तत्व द्वारा क्रमबद्ध करना चाहते हैं, फिर दूसरा। हमसी # सूची <> x द्वारा क्रमबद्ध करें y

SELECT * from Table ORDER BY x, y 

के कार्यात्मक समकक्ष हम एक वर्ग है कि छँटाई कार्यों के एक नंबर शामिल है हासिल करना चाहते हैं, और हम एक ही तत्व से छँटाई कोई मुद्दा नहीं है।
उदाहरण के लिए:

public class MyClass { 
    public int x; 
    public int y; 
} 

List<MyClass> MyList; 

public void SortList() { 
    MyList.Sort(MySortingFunction); 
} 

और हम सूची में निम्नलिखित है:

Unsorted  Sorted(x)  Desired 
--------- --------- --------- 
ID x y ID x y ID x y 
[0] 0 1 [2] 0 2 [0] 0 1 
[1] 1 1 [0] 0 1 [2] 0 2 
[2] 0 2 [1] 1 1 [1] 1 1 
[3] 1 2 [3] 1 2 [3] 1 2 

स्थिर तरह बेहतर होगा, लेकिन जरूरी नहीं। समाधान जो .NET 2.0 के लिए काम करता है स्वागत है।

+0

@Bolu मैं स्पष्ट रूप से पोस्ट संस्करण नास्तिक और अद्यतन जवाब है कि मैच के लिए बनाने के लिए टैग निकाल दिया है। यदि आपको लगता है कि 4.0/2.0 पर्याप्त महत्वपूर्ण नहीं था तो टैग को पुनर्स्थापित करने के बजाय प्रश्न में एक स्पष्ट संपादन करने पर विचार करें। –

+0

क्षमा करें @AlexeiLevenkov, अधिक ध्यान नहीं दिया, कृपया रोल-बैक करने के लिए स्वतंत्र महसूस करें। – Bolu

+0

ठीक है। परिवर्तन वापस कर दिया। –

उत्तर

97

ध्यान रखें कि यदि आप सभी सदस्यों की तुलना करते हैं तो आपको स्थिर प्रकार की आवश्यकता नहीं है। 2.0 समाधान, के रूप में अनुरोध किया है, इस तरह दिख सकता:

public void SortList() { 
    MyList.Sort(delegate(MyClass a, MyClass b) 
    { 
     int xdiff = a.x.CompareTo(b.x); 
     if (xdiff != 0) return xdiff; 
     else return a.y.CompareTo(b.y); 
    }); 
} 

कि इस 2.0 समाधान अभी भी लोकप्रिय 3.5 Linq समाधान से अधिक पसंद किया जाता है ध्यान दें करो, यह एक में जगह तरह करता है और हे नहीं है (एन) लिंक दृष्टिकोण की भंडारण आवश्यकता। जब तक आप मूल सूची ऑब्जेक्ट को निश्चित रूप से छूने के लिए पसंद नहीं करते हैं।

150

नेट के संस्करण जहां LINQ OrderBy और ThenBy उपयोग कर सकते हैं (या ThenByDescending यदि आवश्यक हो तो) के लिए:

using System.Linq; 
.... 
List<SomeClass>() a; 
List<SomeClass> b = a.OrderBy(x => x.x).ThenBy(x => x.y).ToList(); 

नोट: नेट 2.0 (या आप LINQ उपयोग नहीं कर सकते हैं) के लिए इस प्रश्न के लिए Hans Passant answer देखें।

+2

यहां एक अन्य उत्तर पोस्ट से फूग द्वारा: http://stackoverflow.com/questions/9285426/orderby-and-list-vs-iorderedenumerable यह मूल वस्तुओं के साथ एक नई सूची में एक और सूची बनाता है। यह केवल तभी उपयोगी होता है जब आपको किसी अन्य उद्देश्य के लिए मूल क्रम को संरक्षित करने की आवश्यकता होती है; यह जगह – dreamerkumar

+0

पर सूची को सॉर्ट करने की तुलना में स्मृति की अधिक अपर्याप्त है, ध्यान दें: फिर इसका मूल्यांकन नहीं किया जाता है, भले ही इसका उपयोग नहीं किया जाता है ... –

7

आपको IComparer इंटरफ़ेस को लागू करने की आवश्यकता है। उदाहरण कोड के साथ Here's a good post

5

चाल एक स्थिर प्रकार को लागू करने के लिए है। मैं एक विजेट वर्ग है कि अपने परीक्षण डाटा शामिल कर सकते हैं बना लिया है:

public class Widget : IComparable 
{ 
    int x; 
    int y; 
    public int X 
    { 
     get { return x; } 
     set { x = value; } 
    } 

    public int Y 
    { 
     get { return y; } 
     set { y = value; } 
    } 

    public Widget(int argx, int argy) 
    { 
     x = argx; 
     y = argy; 
    } 

    public int CompareTo(object obj) 
    { 
     int result = 1; 
     if (obj != null && obj is Widget) 
     { 
      Widget w = obj as Widget; 
      result = this.X.CompareTo(w.X); 
     } 
     return result; 
    } 

    static public int Compare(Widget x, Widget y) 
    { 
     int result = 1; 
     if (x != null && y != null)     
     {     
      result = x.CompareTo(y); 
     } 
     return result; 
    } 
} 

मैं, IComparable लागू किया तो यह unstably() List.Sort के अनुसार क्रमबद्ध जा सकता है।

हालांकि, मैंने स्थैतिक विधि तुलना भी लागू की, जिसे एक खोज विधि के प्रतिनिधि के रूप में पारित किया जा सकता है।

मैं C# 411 से इस प्रविष्टि प्रकार विधि उधार:

public static void InsertionSort<T>(IList<T> list, Comparison<T> comparison) 
     {   
      int count = list.Count; 
      for (int j = 1; j < count; j++) 
      { 
       T key = list[j]; 

       int i = j - 1; 
       for (; i >= 0 && comparison(list[i], key) > 0; i--) 
       { 
        list[i + 1] = list[i]; 
       } 
       list[i + 1] = key; 
      } 
    } 

आप प्रकार सहायकों वर्ग है कि आप अपने प्रश्न में आपका उल्लेख में रखते हैं।

अब, यह उपयोग करने के लिए:

static void Main(string[] args) 
    { 
     List<Widget> widgets = new List<Widget>(); 

     widgets.Add(new Widget(0, 1)); 
     widgets.Add(new Widget(1, 1)); 
     widgets.Add(new Widget(0, 2)); 
     widgets.Add(new Widget(1, 2)); 

     InsertionSort<Widget>(widgets, Widget.Compare); 

     foreach (Widget w in widgets) 
     { 
      Console.WriteLine(w.X + ":" + w.Y); 
     } 
    } 

और यह आउटपुट:

0:1 
0:2 
1:1 
1:2 
Press any key to continue . . . 

यह शायद कुछ अनाम प्रतिनिधियों से साफ किया जा सकता है, लेकिन मैं आप के लिए है कि ऊपर छोड़ देंगे।

संपादित करें: और नोबगज़ अनाम विधियों की शक्ति का प्रदर्शन करता है ...इसलिए, मेरा अधिक पुरानास्कूल मानें: पी

+0

वाह, जोनाथन, ऊपर और परे धन्यवाद! –

1

मुझे एक समस्या थी जहां ऑर्डरबी और फिरबी ने मुझे वांछित परिणाम नहीं दिया (या मुझे नहीं पता था कि उन्हें सही तरीके से कैसे उपयोग किया जाए)।

मैं एक सूची के साथ गया। इस तरह कुछ समाधान समाधान।

var data = (from o in database.Orders Where o.ClientId.Equals(clientId) select new { 
    OrderId = o.id, 
    OrderDate = o.orderDate, 
    OrderBoolean = (SomeClass.SomeFunction(o.orderBoolean) ? 1 : 0) 
    }); 

    data.Sort((o1, o2) => (o2.OrderBoolean.CompareTo(o1.OrderBoolean) != 0 
    o2.OrderBoolean.CompareTo(o1.OrderBoolean) : o1.OrderDate.Value.CompareTo(o2.OrderDate.Value))); 
संबंधित मुद्दे