开发者

using Comparer to sort IEnumerable in C# by different fields

开发者 https://www.devze.com 2022-12-21 21:30 出处:网络
I have a list of an object which need to be sorted depending on t开发者_如何学Chree different properties of the object.

I have a list of an object which need to be sorted depending on t开发者_如何学Chree different properties of the object. Example

CLass Object1{ Property1 , Property2, Property3}

ListObj = IEnumerable<Object1>

Foreach ( item in ListObj){

    if (item.Property1 == true)
       item goes at top of list
    if(item.Property2 == true)
       item goes end of list
    if(item.Property3 == true)
        item can go anywhere.
}

End list should be objects with Property1 = true followed by objects with Property2 = true followed by objects with Property3 = true


Why not use LINQ?

var orderedList = 
   ListObj.OrderByDescending(x => x.Property1)
          .ThenByDescending(x => x.Property2);


Your own title already says it all: implement a custom IComparer<Object1> and pass it to the OrderBy extension method:

var orderedItems = ListObj.OrderBy(obj => obj, customComparer);


You can make things neater for yourself if you define this type:

  public class ComparisonComparer<T> : IComparer<T>  
  {  
      private readonly Comparison<T> _comparison;  

      public ComparisonComparer(Comparison<T> comparison)  
      {  
          _comparison = comparison;  
      }  

      public int Compare(T x, T y)  
      {  
          return _comparison(x, y);  
      }  
 }  

Which lets you define the comparison inline with the LINQ statement using a lambda expression.


This should provide the required sorting (according to the code, not the statement below).

ListObj.Where(x => x.Property1 == true)
       .Concat(ListObj.Where(x => x.Property1 == false && x.Property2 == false))
       .Concat(ListObj.Where(x => x.Property2 == true));


i think you want to define a comparison function where you can determine rank between any 2 items in the list.

    int CompareObject1(Object1 left, Object1 right)
    {
        // TODO: cases where your items are null

        // compare Property1 values
        if (left.Property1)
        {
            if (right.Property1)
            {
                // items at same rank
                return 0;
            }
            else
            {
                // left item is higher rank than right
                return -1;
            }
        }
        else if (right.Property1)
        {
            // right item is higher rank than left
            return 1;
        }

        // Property1 doesn't indicate position, move along
        // TODO: repeat for Property2

        // Property2 doesn't indicate position, move along
        // TODO: repeat for Property3

        // if we get here, no determination can 
        // be made/don't bother to move anything
        return 0;
    }

the return value indicates if the left or right object should be ranked higher with -1 or 1 (or 0 for preference). just make sure you cover all your conditions.

then you can use this like

List<Object1> foo = new List<Object1>() { <items...> };
foo.Sort(CompareObject1);

if you're list ends up backwards, i probably flipped the signs in the compare function. your rules for sorting are contradictory so i'll let you sort Property2 and Property3.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号