如何按C#中的特定字段对对象列表进行排序?

时间:2009-08-19 18:34:40

标签: c# sorting

我有这堂课:

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 个答案:

答案 0 :(得分:61)

使用LINQ:

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

对原始列表进行排序:

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

答案 1 :(得分:15)

无论如何,我看到你已经得到了答案,但是......

  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,仍然可以通过LINQBridge使用LINQ。

  4. 这是第二个答案所需的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));
        }
    }
    

答案 2 :(得分:4)

为了说明Robert C. Cartaino的回答:

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

不是最通用的解决方案,但如果您只按日期排序则很好。而且,正如Robert所说,您仍然可以通过将IComparer参数传递给sort方法来覆盖默认排序。

答案 3 :(得分:3)

使用lambda表达式将一对映射到比较:

_allStatInfo.Sort((x, y) => x.date - y.date);

答案 4 :(得分:2)

它对我有用ُSorting array of custom type using delegate

// 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 + " ");

答案 5 :(得分:1)

对于DateTime,不需要进行比较。

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

_allStatInfo.OrderByDescending(d => d.Date);