tags:

views:

437

answers:

5

I have a list of an object which need to be sorted depending on three 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

+2  A: 

Why not use LINQ?

var orderedList = 
   ListObj.OrderByDescending(x => x.Property1)
          .ThenByDescending(x => x.Property2);
David Morton
Does not provide the right sorting as required by the OP.
Obalix
@Obalix: What is the right sorting indicated by the OP? He indicates two possibilities... his code hints at one possibility, while the text after his code indicates another. And by the way, true comes after false with a simple OrderBy. OrderByDescending makes true come first.
David Morton
You are right, sorry!
Obalix
+2  A: 

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

Mark Seemann
A: 

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));
Obalix
A: 

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.

MikeP
A: 

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.

lincolnk