C # सूची <> x द्वारा क्रमबद्ध करें तब y


88

करने के लिए इसी तरह की सूची <> OrderBy वर्णमाला आदेश , हम एक तत्व है, तो किसी अन्य के द्वारा क्रमबद्ध करना चाहते हैं। हम कार्यात्मक समकक्ष प्राप्त करना चाहते हैं

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 के लिए काम करने वाले समाधान का स्वागत है।


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

क्षमा करें @AlexeiLevenkov, ज्यादा ध्यान न दें, कृपया बेझिझक रोल-बैक करें।
बोलू

ठीक है। परिवर्तन वापस कर दिया।
अलेक्सई लेवेनकोव

यह सवाल मूल 2.0 से .Net के सभी संस्करणों को कवर करने के लिए अद्यतन किया गया था - इसमें विभिन्न रूपरेखाओं और आवश्यकताओं के लिए कई वैकल्पिक उत्तर शामिल हैं - यह देखने के लिए सभी जांचें कि आपकी आवश्यकताओं में से कौन सा बेहतर है।
अलेक्सई लेवेनकोव

जवाबों:


98

ध्यान रखें कि यदि आप सभी सदस्यों की तुलना करते हैं तो आपको एक स्थिर प्रकार की आवश्यकता नहीं है। अनुरोध के रूप में 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);
     });
 }

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


156

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

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

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


2
यहाँ एक और उत्तर पोस्ट से फॉग द्वारा: stackoverflow.com/questions/9285426/… यह एक नए क्रम में मूल वस्तुओं के साथ एक और सूची बनाता है। यह केवल तभी उपयोगी है जब आपको किसी अन्य उद्देश्य के लिए मूल ऑर्डर को संरक्षित करने की आवश्यकता होती है; यह जगह में सूची को छांटने की तुलना में स्मृति की अधिक बेकार है
स्वप्नकुमार


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 को लागू किया है, इसलिए इसे 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 . . .

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

संपादित करें : और NoBugz अनाम तरीकों की शक्ति को प्रदर्शित करता है ... इसलिए, मेरा और अधिक सुनहरा विचार करें: पी



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