开发者

C# list sort by two columns

开发者 https://www.devze.com 2023-03-29 08:49 出处:网络
I have a C# custom object list that I need to sort by two different variables one is a boolean and the other is a string. I can sort by either of the criteria, but I\'m having trouble figuring out how

I have a C# custom object list that I need to sort by two different variables one is a boolean and the other is a string. I can sort by either of the criteria, but I'm having trouble figuring out how to combine them. The sort should be all of the boolean values first (CheckedIn) and then the last name for each of the values. Right now I use

result.Sort((x, y) => string.Compare(x.CheckedIn.ToString(), y.CheckedIn.ToString()));
result.Sort((x, y) => string.Compare(x.LastName, y.LastName));

But how can I combine then so that my results are like

开发者_开发问答
CheckedIn-Name
No - Aames
No - Smith
Yes - Barnes
Yes - Peters


use linq.

if you have list L of objects of class

public class temp
{
public bool x;
public string y;
}

then use:

L.orderby(a=>a.x).thenby(a=>a.y);

you can chain it as far as you like.


result.Sort((x,y) => x.CheckedIn==y.CheckedIn ? 
  string.Compare(x.LastName, y.LastName) : 
  (x.CheckedIn ? -1 : 1) );


var sortResult = result.OrderBy(a => a.CheckedIn).ThenBy(a => a.LastName).ToList();


I have a class that creates CSV files using List<List<string>> in a _Records variable. I needed way to sort it after the fact, and LINQ was no good.

This is what I created as a multi-sort by passing in the indexes of the columns I wanted to sort.

public void OrderBy(params int[] columnIndexes)
{
    _Records.Sort((x, y) =>
    {
        foreach (int i in columnIndexes)
        {
            int result = string.Compare(x[i], y[i]);
            if (result != 0)
                return result;
        }
        return 0;
    });
}

Usage would then be...

csv.OrderBy(1, 3, 5);


Here is an extension method I wrote for sorting a list by any number of keys:

public static class ListExtensions
{
    public static void SortBy<T>(this List<T> list, params Expression<Func<T, IComparable>>[] keys)
    {
        if (list == null)
            throw new ArgumentNullException("list");
        if(keys == null || !keys.Any())
            throw new ArgumentException("Must have at least one key!");
        list.Sort((x, y) => (from selector in keys 
                             let xVal = selector.Compile()(x) 
                             let yVal = selector.Compile()(y) 
                             select xVal.CompareTo(yVal))
                             .FirstOrDefault(compared => compared != 0));
    }
}

Usage:

var List<Person> persons = GetPersons();
myList.SortBy(p => p.LastName, p => p.FirstName);

Note that this is roughly equivalent to: myList = myList.OrderBy(p => p.LastName).ThenBy(p => p.FirstName).


I was able to do something fast/dirty by doing this.. since both columns are text, just add them together to sort in one quick pass.

this.Project.Tasks.Sort((x, y) => String.Compare((x.Assignee + x.Task), (y.Assignee + y.Task)));


Comparison Chain in C#

Here's my comparison chain solution. It will take care of aggregating all comparer classes you are interested in sorting by. the builder pattern makes it easy to provide columns to sort by and get a sorted list in return.

0

精彩评论

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