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




generics list (16)

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

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

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

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

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

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


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

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

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 शैली 'ऑर्डरबी' करने का एक बेवकूफ अनावश्यक जटिल तरीका है, लेकिन यह आपको एक संकेत दे सकता है कि इसे सामान्य तरीके से कैसे कार्यान्वित किया जा सकता है


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

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);
    }

//Get data from database, then sort list by staff name:

List<StaffMember> staffList = staffHandler.GetStaffMembers();

var sortedList = from staffmember in staffList
                 orderby staffmember.Name ascending
                 select staffmember;

उपर्युक्त उत्तरों में से कोई भी मेरे लिए सामान्य नहीं था इसलिए मैंने इसे बनाया:

var someUserInputStringValue = "propertyNameOfObject i.e. 'Quantity' or 'Date'";
var SortedData = DataToBeSorted
                   .OrderBy(m => m.GetType()
                                  .GetProperties()
                                  .First(n => 
                                      n.Name == someUserInputStringValue)
                   .GetValue(m, null))
                 .ToList();

हालांकि बड़े पैमाने पर डेटा सेट पर सावधान। यह आसान कोड है लेकिन यदि संग्रह विशाल है और संग्रह के ऑब्जेक्ट प्रकार में बड़ी संख्या में फ़ील्ड हैं तो आपको परेशानी हो सकती है। रन टाइम एनएक्सएम है जहां:

संग्रह में तत्वों के एन = #

ऑब्जेक्ट के भीतर गुणों का एम = #


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

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 एक्सटेंशन विधि है जो सूची की एक अतिरिक्त प्रति नहीं बनाता है:

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)));
}

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

सबसे पहले मुझे 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" (या तर्क ऑपरेटर, आपकी पसंद) को स्वैप करना सॉर्ट ऑर्डर को उलट देता है।


लीएनक्यू ऑर्डरबी का उपयोग करें

List<Order> objListOrder=new List<Order> ();
    objListOrder=GetOrderList().OrderBy(o=>o.orderid).ToList();

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

ORDER BY OrderDate, OrderId

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

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

कृपया मुझे कुछ नमूना कोड के साथ @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 ...
}

var obj = db.Items.Where...

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

रोजर के संस्करण में सुधार हुआ।

GetDynamicSortProperty के साथ समस्या यह है कि केवल संपत्ति के नाम प्राप्त होते हैं लेकिन क्या होता है यदि ग्रिड व्यू में हम नेविगेशन प्रॉपर्टीज का उपयोग करते हैं? यह एक अपवाद भेज देगा, क्योंकि यह शून्य लगता है।

उदाहरण:

"कर्मचारी.कंपनी.अम;" क्रैश हो जाएगा ... क्योंकि इसका मूल्य प्राप्त करने के लिए पैरामीटर के रूप में केवल "नाम" की अनुमति है।

यहां एक बेहतर संस्करण है जो हमें नेविगेशन गुणों द्वारा क्रमबद्ध करने की अनुमति देता है।

public object GetDynamicSortProperty(object item, string propName)
    {
        try
        {                 
            string[] prop = propName.Split('.'); 

            //Use reflection to get order type                   
            int i = 0;                    
            while (i < prop.Count())
            {
                item = item.GetType().GetProperty(prop[i]).GetValue(item, null);
                i++;
            }                     

            return item;
        }
        catch (Exception ex)
        {
            throw ex;
        }


    } 

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

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);  

प्रदर्शन बिंदु से, क्रमबद्ध सूची का उपयोग करना सबसे अच्छा है ताकि डेटा को क्रमबद्ध किया जा सके क्योंकि परिणाम में जोड़ा गया है। अन्य दृष्टिकोणों को डेटा पर कम से कम एक अतिरिक्त पुनरावृत्ति की आवश्यकता होती है और अधिकांश डेटा की एक प्रति बनाते हैं, न केवल प्रदर्शन बल्कि स्मृति उपयोग भी प्रभावित होंगे। सैकड़ों तत्वों के साथ कोई मुद्दा नहीं हो सकता है लेकिन हजारों के साथ होगा, खासकर उन सेवाओं में जहां कई समवर्ती अनुरोध एक ही समय में सॉर्ट कर सकते हैं। System.Collections.Generic नेमस्पेस पर एक नज़र डालें और सूची के बजाय सॉर्टिंग के साथ एक वर्ग चुनें।

और जब संभव हो तो प्रतिबिंब का उपयोग करके जेनेरिक कार्यान्वयन से बचें, इससे प्रदर्शन के मुद्दे भी हो सकते हैं।





sorting