vinco83
vinco83

Reputation: 497

List.Sort (Custom sorting...)

I have a List object that includes 3 items: Partial, Full To H, and Full To O.

I'm binding this list to an asp OptionButtonList, and it's sorting it in alphabetical order. However, I want to sort the list like the following:

Full To H, Partial, Full To O.

How can I accomplish this?

Upvotes: 24

Views: 39628

Answers (8)

vinco83
vinco83

Reputation: 497

I did it like this:

List<string> sortedList = list
    .OrderBy(i => i.CodeValue == "FullToH")
    .ThenBy(i => i.CodeValue == "Partial")
    .ThenBy(i => i.CodeValue == "FullToO")
    .ToList();

Then binded to the sortedList!

Upvotes: 19

valentasm
valentasm

Reputation: 2412

Lets say you have items of string and you want prioritize them by other list priorities. Here is my example where i have list of priorities which these will be first in sorted list by their priority.

Result

kitty , some item , kk abb , ccc , kk abc, some flash
class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var input = new List<string>()
            {
                "some item",
                "some flash",
                "kitty",
                "ccc",
                "kk abc",
                "kk abb"

            };

            var sorted = input.OrderBy(x => x, new Comparer()).ToList();

            Console.ReadKey();
        }
    }

    public class Comparer : IComparer<string>
    {
        private List<KeyValuePair<string, int>> priorities = new List<KeyValuePair<string, int>>()
        {
            new KeyValuePair<string, int>("some item", 2),
            new KeyValuePair<string, int>("kitty", 1),
            new KeyValuePair<string, int>("kk abb", 3),
        };
        public int Compare(string x, string y)
        {
            var anyX = priorities.Any(z => z.Key == x);
            var anyY = priorities.Any(z => z.Key == y);
            if (anyX || anyY)
            {
                var firstX = priorities.FirstOrDefault(z => z.Key == x);
                var firstY = priorities.FirstOrDefault(z => z.Key == y);
                if (anyX && anyY)
                {
                    if (firstX.Value > firstY.Value)
                    {
                        return firstX.Value;
                    }

                    return -firstX.Value;
                }

                if (anyX)
                {
                    return -firstX.Value;
                }

                if (anyY)
                {
                    return firstY.Value;
                }

            }


            return string.Compare(x, y, StringComparison.Ordinal);
        }
    }

Upvotes: 0

jjjjs
jjjjs

Reputation: 1650

Ok, I know this is a few years old but I have an alternative solution that I think is more elegant than the above solutions that future readers might want to consider:

In your class:

static readonly List<String> codeValueSortOrder = new List<String> {
    "Full To H", 
    "Partial",
    "Full To O"
};

and in your method:

sortedList = list.OrderBy(i=> codeValueSortOrder.IndexOf(i.CodeValue));

Upvotes: 24

Gabriel McAdams
Gabriel McAdams

Reputation: 58293

Assuming that your list is not

 List<object> myList = new List<object>();

but instead, something like

List<MyObjectClass> myList = new List<MyObjectClass>();

(where each element is of the same object type)

You could do this:

myList.Sort((firstObj, secondObj) =>
    {
        return firstObj.SomeProperty.CompareTo(secondObj.SomeProperty);
    }
);

Upvotes: 4

JaredPar
JaredPar

Reputation: 755317

Are the items you listed (FullToHo for example) just strings? If so then all you need to do is to write a method to do the comparison and sort with that method.

public int CompareEntries(string left, string right) {
  const string fullToH = "Full To H";
  const string partial = "Partial";
  const string fullToO = "Full To O";
  if ( left == right ) {
    return 0;
  } else if ( left == fullToH ) {
    return -1;
  } else if ( left == fullToO ) {
    return 1;
  } else if ( right == fullToH ) {
    return 1;
  } else {
    return -1; 
  }
}

list.Sort(CompareEntries);

Upvotes: 11

Justin Niessner
Justin Niessner

Reputation: 245479

Create a Comparer for your custom type (which implements the IComparer interface). You can then use that to sort the List:

List<CustomType> list = new List<CustomType>();

// Fill list
list.Sort(new CustomComparer());

Or if you're using a newer version of the framework and don't need to re-use the sorting logic, you could use the IEnumerable<T>.OrderBy() method.

Upvotes: 0

Kelsey
Kelsey

Reputation: 47766

Linq is great for this. You could even build the order sequence up to have it defined on the fly since the execution of the sort is not executed until the ToList.

 var sortedList = yourList.OrderBy(i => i.FullToH).
     ThenBy(i => i.Partial).
     ThenBy(i => i.FullToO).ToList();

Upvotes: 30

Related Questions