c# - বস্তুর একটি সম্পত্তি দ্বারা একটি তালিকা<T> কীভাবে সাজান




generics list (13)

// একটি গ্রিডভিউ সঙ্গে ব্যবহারের জন্য সম্পূর্ণরূপে জেনেরিক বাছাই

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 নামক একটি ক্লাস আছে যার মধ্যে OrderId , OrderDate , Quantity এবং Total হিসাবে বৈশিষ্ট্য রয়েছে। আমার এই Order ক্লাসের একটি তালিকা আছে:

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

এখন আমি Order বস্তুর এক সম্পত্তিের উপর ভিত্তি করে তালিকাটি সাজতে চাই, উদাহরণস্বরূপ আমি অর্ডার তারিখ বা অর্ডার আইডি অনুসারে সাজানোর প্রয়োজন।

আমি কিভাবে এই # সি করতে পারেন?


LINQ ছাড়া .NET2.0 এ এটি করতে:

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

যদি আপনি .Net3.0 এ থাকেন তবে LukeH এর 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;
    }
);

এই আপনি descending আদেশ ID সঙ্গে ascending তারিখ দিতে হবে।

যাইহোক, আমি প্রতিনিধিদের স্টিক করার সুপারিশ করব না কারণ এটি কোড পুনঃব্যবহার ছাড়া প্রচুর জায়গা অর্থাত্ হবে। আপনি একটি 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 ক্লাসটি ব্যবহার করতে, এটি কেবল তাত্ক্ষণিক করুন এবং আপনার সাজানোর পদ্ধতিতে প্রেরণ করুন:

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

Nullable ধরনের সঙ্গে কাজ করে যে কেউ, CompareTo ব্যবহার করার জন্য Value প্রয়োজন বোধ করা হয়।

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


আপনি বৈশিষ্ট্যের নির্বাচন সম্পর্কে আরো জেনেরিক কিছু করতে পারেন তবে আপনার ক্ষেত্রে 'অর্ডার' থেকে আপনি যে ধরনের প্রকারের নির্বাচন করছেন তা সম্পর্কে নির্দিষ্ট হতে পারেন:

একটি জেনেরিক হিসাবে আপনার ফাংশন লিখুন:

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

একটি লিনকিউ স্টাইল 'অর্ডারবি' করার একটি মূঢ় অপ্রয়োজনীয় জটিল উপায় যা, তবে এটি আপনাকে একটি জেনেরিক ভাবে প্রয়োগ করা যায় এমন একটি সূত্র দিতে পারে


একটি তালিকা অর্ডার করার OrderBy উপায় OrderBy ব্যবহার করা OrderBy

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

আপনি নিম্নলিখিত SQL মতামত মত একাধিক কলাম দ্বারা অর্ডার করতে চান।

ORDER BY OrderDate, OrderId

এই অর্জন করার জন্য আপনি নিম্নলিখিত মত ব্যবহার করতে পারেন।

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

এখানে একটি জেনেরিক 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)));
}

দয়া করে আমাকে @ লুকহ দ্বারা কিছু নমুনা কোড দিয়ে উত্তরটি সম্পূর্ণ করতে দিন, যেমন আমি এটি পরীক্ষা করেছি আমি বিশ্বাস করি এটি কিছুের জন্য কার্যকর হতে পারে:

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 ...
}

যদি তালিকায় থাকা তালিকাটি সাজানোর প্রয়োজন হয় তবে আপনি Comparison<T> পদ্ধতিটি ব্যবহার করতে পারেন Comparison<T> একটি Comparison<T> প্রতিনিধি Comparison<T> প্রতিনিধি:

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

আপনি যদি OrderBy সাজানোর পরিবর্তে একটি নতুন, সাজানো ক্রম তৈরি করতে পছন্দ করেন তবে অন্য উত্তরগুলির মধ্যে উল্লিখিত হিসাবে আপনি LINQ এর OrderBy পদ্ধতিটি ব্যবহার করতে পারেন।


লিংক ব্যতীত আপনি এটা করছেন:

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 () কল করুন


লিনক ব্যবহার করার সবচেয়ে সহজ উপায় আমি মনে করতে পারি:

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

একটি ক্লাসিক্যাল অবজেক্ট ওরিয়েন্টেড সমাধান

প্রথমত, আমি LINQ এর অতিপ্রাকৃততা সম্পর্কে জেনে নেব .... এখন যেভাবে আমরা এটিকে খুঁজে পেয়েছি

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

এই পরিস্থিতিতে, আপনাকে অবশ্যই মাইওরোডিং ক্ল্যাস হিসাবে তা তাত্পর্যপূর্ণ করতে হবে (বরং 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