c# - ऑब्जेक्ट में किसी संपत्ति द्वारा<T> सूची को कैसे क्रमबद्ध करें




generics list (13)

.NET2.0 पर LINQ के बिना ऐसा करने के लिए:

List<Order> objListOrder = GetOrderList();
objListOrder.Sort(
    delegate(Order p1, Order p2)
    {
        return p1.OrderDate.CompareTo(p2.OrderDate);
    }
);

यदि आप .Net3.0 पर हैं, तो ल्यूकएच का answer वह है जो आप कर रहे हैं।

एकाधिक गुणों को सॉर्ट करने के लिए, आप इसे अभी भी एक प्रतिनिधि के भीतर कर सकते हैं। उदाहरण के लिए:

orderList.Sort(
    delegate(Order p1, Order p2)
    {
        int compareDate = p1.Date.CompareTo(p2.Date);
        if (compareDate == 0)
        {
            return p2.OrderID.CompareTo(p1.OrderID);
        }
        return compareDate;
    }
);

यह आपको अवरोही आदेश आईडी के साथ आरोही तिथियां देगा।

हालांकि, मैं प्रतिनिधियों को चिपकाने की अनुशंसा नहीं करता क्योंकि इसका मतलब कोड के पुन: उपयोग के बिना बहुत से स्थानों का होगा। आपको एक IComparer लागू करना चाहिए और बस अपनी Sort विधि के माध्यम से इसे पास करना चाहिए। here देखें

public class MyOrderingClass : IComparer<Order>
{
    public int Compare(Order x, Order y)
    {
        int compareDate = x.Date.CompareTo(y.Date);
        if (compareDate == 0)
        {
            return x.OrderID.CompareTo(y.OrderID);
        }
        return compareDate;
    }
}

और फिर इस आईसीओएमपीयर कक्षा का उपयोग करने के लिए, बस इसे तुरंत चालू करें और इसे अपनी सॉर्ट विधि पर पास करें:

IComparer<Order> comparer = new MyOrderingClass();
orderList.Sort(comparer);

मेरे पास Order नामक एक वर्ग है जिसमें Order OrderId , OrderId , Quantity और Total जैसे गुण हैं। मेरे पास इस Order क्लास की एक सूची है:

List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders

अब मैं Order ऑब्जेक्ट की एक प्रॉपर्टी के आधार पर सूची को सॉर्ट करना चाहता हूं, उदाहरण के लिए मुझे ऑर्डर डेट या ऑर्डर आईडी द्वारा सॉर्ट करना होगा।

मैं इसे सी # में कैसे कर सकता हूं?


// ग्रिडव्यू के साथ उपयोग के लिए पूरी तरह से जेनेरिक सॉर्टिंग

public List<T> Sort_List<T>(string sortDirection, string sortExpression, List<T> data)
    {

        List<T> data_sorted = new List<T>();

        if (sortDirection == "Ascending")
        {
            data_sorted = (from n in data
                              orderby GetDynamicSortProperty(n, sortExpression) ascending
                              select n).ToList();
        }
        else if (sortDirection == "Descending")
        {
            data_sorted = (from n in data
                              orderby GetDynamicSortProperty(n, sortExpression) descending
                              select n).ToList();

        }

        return data_sorted;

    }

    public object GetDynamicSortProperty(object item, string propName)
    {
        //Use reflection to get order type
        return item.GetType().GetProperty(propName).GetValue(item, null);
    }

अगर आपको कुछ चाहिए

ORDER BY OrderDate, OrderId

फिर निम्नलिखित की तरह कोशिश करें।

  List<Order> objListOrder = 
    source.OrderBy(order => order.OrderDate).ThenBy(order => order.OrderId).ToList();

आप प्रॉपर्टी चयन के बारे में कुछ और सामान्य कर सकते हैं, फिर भी आप जिस प्रकार से चुन रहे हैं उसके बारे में विशिष्ट हो, अपने मामले 'ऑर्डर' में:

एक सामान्य के रूप में अपना कार्य लिखें:

public List<Order> GetOrderList<T>(IEnumerable<Order> orders, Func<Order, T> propertySelector)
        {
            return (from order in orders
                    orderby propertySelector(order)
                    select order).ToList();
        } 

और फिर इसे इस तरह उपयोग करें:

var ordersOrderedByDate = GetOrderList(orders, x => x.OrderDate);

आप और भी सामान्य हो सकते हैं और आप जो ऑर्डर करना चाहते हैं उसके लिए एक खुले प्रकार को परिभाषित कर सकते हैं:

public List<T> OrderBy<T,P>(IEnumerable<T> collection, Func<T,P> propertySelector)
        {
            return (from item in collection
                    orderby propertySelector(item)
                    select item).ToList();
        } 

और इसे उसी तरह प्रयोग करें:

var ordersOrderedByDate = OrderBy(orders, x => x.OrderDate);

जो LINQ शैली 'ऑर्डरबी' करने का एक बेवकूफ अनावश्यक जटिल तरीका है, लेकिन यह आपको एक संकेत दे सकता है कि इसे सामान्य तरीके से कैसे कार्यान्वित किया जा सकता है


कृपया मुझे कुछ नमूना कोड के साथ @LukeH द्वारा उत्तर पूरा करने दें, क्योंकि मैंने इसका परीक्षण किया है, मुझे विश्वास है कि यह कुछ के लिए उपयोगी हो सकता है:

public class Order
{
    public string OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public int Quantity { get; set; }
    public int Total { get; set; }

    public Order(string orderId, DateTime orderDate, int quantity, int total)
    {
        OrderId = orderId;
        OrderDate = orderDate;
        Quantity = quantity;
        Total = total;
    }
}

public void SampleDataAndTest()
{
    List<Order> objListOrder = new List<Order>();

    objListOrder.Add(new Order("tu me paulo ", Convert.ToDateTime("01/06/2016"), 1, 44));
    objListOrder.Add(new Order("ante laudabas", Convert.ToDateTime("02/05/2016"), 2, 55));
    objListOrder.Add(new Order("ad ordinem ", Convert.ToDateTime("03/04/2016"), 5, 66));
    objListOrder.Add(new Order("collocationem ", Convert.ToDateTime("04/03/2016"), 9, 77));
    objListOrder.Add(new Order("que rerum ac ", Convert.ToDateTime("05/02/2016"), 10, 65));
    objListOrder.Add(new Order("locorum ; cuius", Convert.ToDateTime("06/01/2016"), 1, 343));


    Console.WriteLine("Sort the list by date ascending:");
    objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

    foreach (Order o in objListOrder)
        Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);

    Console.WriteLine("Sort the list by date descending:");
    objListOrder.Sort((x, y) => y.OrderDate.CompareTo(x.OrderDate));
    foreach (Order o in objListOrder)
        Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);

    Console.WriteLine("Sort the list by OrderId ascending:");
    objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));
    foreach (Order o in objListOrder)
        Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);

    //etc ...
}

कोई भी नामुमकिन प्रकार के साथ काम कर रहा है, तुलना करने के लिए Value की आवश्यकता है।

objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));


यदि आपको सूची में सूची को सॉर्ट करने की आवश्यकता है तो आप एक Comparison<T> प्रतिनिधि को पारित करते हुए Sort विधि का उपयोग कर सकते हैं:

objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));

यदि आप जगह में सॉर्ट करने के बजाए एक नया, क्रमबद्ध अनुक्रम बनाना पसंद करते हैं तो आप अन्य उत्तरों में उल्लिखित LINQ की OrderBy विधि का उपयोग कर सकते हैं।


यहां एक सामान्य LINQ एक्सटेंशन विधि है जो सूची की एक अतिरिक्त प्रति नहीं बनाता है:

public static void Sort<T,U>(this List<T> list, Func<T, U> expression)
    where U : IComparable<U>
{
    list.Sort((x, y) => expression.Invoke(x).CompareTo(expression.Invoke(y)));
}

इसके प्रयेाग के लिए:

myList.Sort(x=> x.myProperty);

मैंने हाल ही में यह अतिरिक्त बनाया है जो एक ICompare<U> स्वीकार करता है, ताकि आप तुलना को अनुकूलित कर सकें। यह आसान था जब मुझे एक प्राकृतिक स्ट्रिंग सॉर्ट करने की आवश्यकता थी:

public static void Sort<T, U>(this List<T> list, Func<T, U> expression, IComparer<U> comparer)
    where U : IComparable<U>
{    
    list.Sort((x, y) => comparer.Compare(expression.Invoke(x), expression.Invoke(y)));
}

लिंक का उपयोग करना सबसे आसान तरीका है:

List<Order> SortedList = objListOrder.OrderBy(o=>o.OrderDate).ToList();

लिंक के बिना इसे करने के रूप में आपने कहा:

public class Order : IComparable
{
    public DateTime OrderDate { get; set; }
    public int OrderId { get; set; }

    public int CompareTo(object obj)
    {
        Order orderToCompare = obj as Order;
        if (orderToCompare.OrderDate < OrderDate || orderToCompare.OrderId < OrderId)
        {
            return 1;
        }
        if (orderToCompare.OrderDate > OrderDate || orderToCompare.OrderId > OrderId)
        {
            return -1;
        }

        // The orders are equivalent.
        return 0;
    }
}

फिर ऑर्डर की अपनी सूची पर बस .sort () पर कॉल करें


एक शास्त्रीय वस्तु उन्मुख समाधान

सबसे पहले मुझे LINQ की उत्कृष्टता के लिए genuflect करना चाहिए .... अब हम उसे रास्ते से बाहर मिल गया है

JimmyHoffa जवाब पर एक बदलाव। जेनेरिक के साथ CompareTo पैरामीटर प्रकार सुरक्षित हो जाता है।

public class Order : IComparable<Order> {

    public int CompareTo( Order that ) {
        if ( that == null ) return 1;
        if ( this.OrderDate > that.OrderDate) return 1;
        if ( this.OrderDate < that.OrderDate) return -1;
        return 0;
    }
}

// in the client code
// assume myOrders is a populated List<Order>
myOrders.Sort(); 

यह डिफ़ॉल्ट क्रमबद्धता निश्चित रूप से फिर से प्रयोग योग्य है। यह है कि प्रत्येक क्लाइंट को सॉर्टिंग तर्क को फिर से लिखना नहीं पड़ता है। "1" और "-1" (या तर्क ऑपरेटर, आपकी पसंद) को स्वैप करना सॉर्ट ऑर्डर को उलट देता है।


जेनेरिक टाइप टाइप की तुलना में:
हम सॉर्टिंग झंडे जोड़कर अधिक लचीलापन प्राप्त कर सकते हैं:

public class MyOrderingClass : IComparer<Order> {  
    public int Compare(Order x, Order y) {  
        int compareDate = x.Date.CompareTo(y.Date);  
        if (compareDate == 0) {  
            int compareOrderId = x.OrderID.CompareTo(y.OrderID);  

            if (OrderIdDescending) {  
                compareOrderId = -compareOrderId;  
            }  
            return compareOrderId;  
        }  

        if (DateDescending) {  
            compareDate = -compareDate;  
        }  
        return compareDate;  
    }  

    public bool DateDescending { get; set; }  
    public bool OrderIdDescending { get; set; }  
}  

इस परिदृश्य में, आपको इसे MyOrderingClass के रूप में तुरंत चालू करना होगा (बल्कि तब IComparer )
अपनी सॉर्टिंग गुण सेट करने के लिए:

MyOrderingClass comparer = new MyOrderingClass();  
comparer.DateDescending = ...;  
comparer.OrderIdDescending = ...;  
orderList.Sort(comparer);  

var obj = db.Items.Where...

var orderBYItemId = obj.OrderByDescending(c => Convert.ToInt32(c.ID));






sorting