排序自定义班级列表<T>


112

我想用该date属性对列表进行排序。

这是我的自定义类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Test.Web
{
    public class cTag
    {
        public int id { get; set; }
        public int regnumber { get; set; }
        public string date { get; set; }
    }
}

这是List我要排序的:

List<cTag> Week = new List<cTag>();

我想要做的是按datecTag类的属性对列表进行排序。日期格式为:dd.MM.yyyy。

我读了一些有关该IComparable接口的内容,但不知道如何使用它。

Answers:


143

一种方法是使用 delegate

List<cTag> week = new List<cTag>();
// add some stuff to the list
// now sort
week.Sort(delegate(cTag c1, cTag c2) { return c1.date.CompareTo(c2.date); });

98
您还可以使用lambda表达式编写相同的内容:list.Sort((a,b) => a.date.CompareTo(b.date));
Xavier Poinas,2010年

2
@Xavier出于某种原因,尽管您100%正确地认为Lambda表达式可以完成工作,而且可能更易于阅读/理解,但我还是总是首先想到谓词。
ahsteele

如何使用lambda表达式始终打平领带?如果a.date == b.date在这里怎么办?list.Sort(((a,b)=> a.date.CompareTo(b.date)); 当分页网格和这两个恰好位于不同的页面上时,这会产生问题吗?
TheEmirOfGroofunkistan'5

1
@TheEmirOfGroofunkistan都取决于如何CompareTo实现。IComparable被授予者,一个类将拥有该方法,但是如何进行比较取决于类创建者。不知道Date是如何实现ICompare的,但是我经常看到开发人员在值相等时使用传递顺序参数来打破平局。hth
ahsteele 2012年

51

您正确的cTag类必须实现IComparable<T>接口。然后,您可以仅Sort()在列表中进行呼叫。

要实现IComparable<T>接口,必须实现CompareTo(T other)方法。最简单的方法是调用要比较的字段的CompareTo方法(在您的情况下为date)。

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public string date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

但是,这种方法不能很好地进行排序,因为它将对字符串使用经典的排序(因为您已将date声明为字符串)。因此,我认为最好的办法是重新定义类并将日期声明为不是字符串,而是声明为DateTime。该代码将几乎保持不变:

public class cTag:IComparable<cTag> {
    public int id { get; set; }
    public int regnumber { get; set; }
    public DateTime date { get; set; }
    public int CompareTo(cTag other) {
        return date.CompareTo(other.date);
    }
}

创建类实例以将包含日期的字符串转换为DateTime类型时,您只需要做的事情,但是可以轻松地完成,例如通过DateTime.Parse(String)方法。


38

对于这种情况,您还可以使用LINQ进行排序:

week = week.OrderBy(w => DateTime.Parse(w.date)).ToList();

12
List<cTag> week = new List<cTag>();
week.Sort((x, y) => 
    DateTime.ParseExact(x.date, "dd.MM.yyyy", CultureInfo.InvariantCulture).CompareTo(
    DateTime.ParseExact(y.date, "dd.MM.yyyy", CultureInfo.InvariantCulture))
);

9

首先,如果date属性正在存储日期,请使用DateTime存储它。如果您通过排序来解析日期,则必须为每个要比较的项目解析日期,这不是很有效...

然后,您可以创建一个IComparer:

public class TagComparer : IComparer<cTag>
{
    public int Compare(cTag first, cTag second)
    {
        if (first != null && second != null)
        {
            // We can compare both properties.
            return first.date.CompareTo(second.date);
        }

        if (first == null && second == null)
        {
            // We can't compare any properties, so they are essentially equal.
            return 0;
        }

        if (first != null)
        {
            // Only the first instance is not null, so prefer that.
            return -1;
        }

        // Only the second instance is not null, so prefer that.
        return 1;
    }
}

var list = new List<cTag>();
// populate list.

list.Sort(new TagComparer());

您甚至可以作为代表来做到这一点:

list.Sort((first, second) =>
          {
              if (first != null && second != null)
                  return first.date.CompareTo(second.date);

              if (first == null && second == null)
                  return 0;

              if (first != null)
                  return -1;

              return 1;
          });

6

没错-您需要实现IComparable。为此,只需声明您的班级:

public MyClass : IComparable
{
  int IComparable.CompareTo(object obj)
  {
  }
}

在CompareTo中,您只需实现自定义比较算法(可以使用DateTime对象执行此操作,但是一定要先检查“ obj”的类型)。有关更多信息,请参见此处此处


7
IComparable<T>可能会是一个更好的选择,因为它优先于IComparable以下位置进行检查:msdn.microsoft.com/en-us/library/b0zbh7b6.aspx
Richard Szalay

5

您可以使用linq:

var q = from tag in Week orderby Convert.ToDateTime(tag.date) select tag;
List<cTag> Sorted = q.ToList()

3

查看List类的重载Sort方法。有一些方法可以做到这一点。其中之一:您的自定义类必须实现IComparable接口,然后可以使用List类的Sort方法。


3

感谢您的所有快速解答。

这是我的解决方案:

Week.Sort(delegate(cTag c1, cTag c2) { return DateTime.Parse(c1.date).CompareTo(DateTime.Parse(c2.date)); });

谢谢


2
YourVariable.Sort((a, b) => a.amount.CompareTo(b.amount));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.