Как отсортировать список объектов по определенному полю в C #? - PullRequest
23 голосов
/ 19 августа 2009

У меня есть этот класс:

public class StatInfo
{
  public string contact;
  public DateTime date;
  public string action;
}

тогда у меня есть список StatInfo, но я не уверен, как его отсортировать по полю даты. Должен ли я использовать метод сортировки? Должен ли я создать свой собственный?

var _allStatInfo = new List<StatInfo>();
// adding lots of stuff in it
_allStatInfo.SortByDate???

Каков наилучший способ сделать это без необходимости писать тонны кода (если это возможно)?

Спасибо

Ответы [ 6 ]

61 голосов
/ 19 августа 2009

Использование LINQ:

var sortedList = _allStatInfo.OrderBy(si => si.date).ToList();

Сортировка исходного списка:

_allStatInfo.Sort(new Comparison<StatInfo>((x, y) => DateTime.Compare(x.date, y.date)));
15 голосов
/ 19 августа 2009

Я вижу, у вас все равно есть ответ, но ...

  1. Вы можете избежать уродства, просто разбив выражение на две половины:

    Comparison<StatInfo> comparison = (x, y) => DateTime.Compare(x.date, y.date);
    _allStatInfo.Sort(comparison);
    

    Возможно, вы захотите просто позвонить CompareTo напрямую:

    Comparison<StatInfo> comparison = (x, y) => x.date.CompareTo(y.date);
    _allStatInfo.Sort(comparison);
    
  2. Вы можете создать реализацию IComparer<T>, используя мой класс ProjectionComparer - это часть MiscUtil , и я включил некомментированную версию в нижней части этот ответ Вы бы тогда написали:

    _allStatInfo.Sort(ProjectionComparer<StatInfo>.Create(x => x.date));
    
  3. Даже если вы используете .NET 2.0, вы все равно можете использовать LINQ с помощью LINQBridge .

Вот класс ProjectionComparer, необходимый для второго ответа. Первые несколько классов на самом деле являются просто помощниками, чтобы позволить выводу общих типов работать лучше.

public static class ProjectionComparer
{
    public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>
        (Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }

    public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>
        (TSource ignored, Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }

}

public static class ProjectionComparer<TSource>
{
    public static ProjectionComparer<TSource, TKey> Create<TKey>
        (Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }
}

public class ProjectionComparer<TSource, TKey> : IComparer<TSource>
{
    readonly Func<TSource, TKey> projection;
    readonly IComparer<TKey> comparer;

    public ProjectionComparer(Func<TSource, TKey> projection)
        : this (projection, null)
    {
    }

    public ProjectionComparer(Func<TSource, TKey> projection,
                              IComparer<TKey> comparer)
    {
        projection.ThrowIfNull("projection");
        this.comparer = comparer ?? Comparer<TKey>.Default;
        this.projection = projection;
    }

    public int Compare(TSource x, TSource y)
    {
        // Don't want to project from nullity
        if (x==null && y==null)
        {
            return 0;
        }
        if (x==null)
        {
            return -1;
        }
        if (y==null)
        {
            return 1;
        }
        return comparer.Compare(projection(x), projection(y));
    }
}
4 голосов
/ 19 августа 2009

Чтобы проиллюстрировать ответ Роберта К. Картейно:

public class StatInfo : IComparable<StatInfo>
{
    public string contact;
    public DateTime date;
    public string action;

    public int CompareTo(StatInfo value)
    {
        return this.date.CompareTo(value.date);
    }
}

var _allStatInfo = new List<StatInfo>();

// this now sorts by date
_allStatInfo.Sort();

Не самое общее решение, но хорошо, если вы собираетесь сортировать только по дате. И, как сказал Роберт, вы все равно всегда можете переопределить сортировку по умолчанию, передав параметр IComparer методу сортировки.

3 голосов
/ 19 августа 2009

Используйте лямбда-выражение, чтобы сопоставить пару для сравнения:

_allStatInfo.Sort((x, y) => x.date - y.date);
2 голосов
/ 19 мая 2015

у меня сработало array Сортировка массива пользовательского типа с использованием делегата

// sort array by name
Array.Sort(users, delegate(User user1, User user2) 
           {
             return user1.Name.CompareTo(user2.Name);
           });
// write array (output: Betty23 Lisa25 Susan20)
foreach (User user in users) Console.Write(user.Name + user.Age + " ");
1 голос
/ 19 августа 2009

Для DateTime не нужно сравнивать.

_allStatInfo.OrderyBy(d => d.date);

или

_allStatInfo.OrderByDescending(d => d.Date);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...