【问题标题】:Sort a Custom Class List<T>对自定义类列表进行排序<T>
【发布时间】:2011-03-10 23:40:10
【问题描述】:

我想使用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>();

我想通过cTag 类的date 属性对List 进行排序。 日期格式为dd.MM.yyyy

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

【问题讨论】:

    标签: c# sorting


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      一种方法是使用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); });
      

      【讨论】:

      • 你也可以用 lambda 表达式写同样的东西:list.Sort((a,b) =&gt; a.date.CompareTo(b.date));
      • @Xavier 出于某种原因,我仍然总是首先跳到谓词上,尽管您 100% 正确地认为您的 Lambda 表达式可以完成工作并且可能更容易阅读/理解。
      • 如何使用 lambda 表达式,或者您将如何始终如一地打破平局?如果 a.date == b.date 在这里怎么办? list.Sort((a,b) => a.date.CompareTo(b.date));当分页网格并且这两个恰好落在不同的页面上时,这会产生问题吗?
      • @TheEmirOfGroofunkistan 这一切都取决于CompareTo 的实现方式。 IComparable 被授予一个类将拥有该方法,但它如何进行比较取决于类创建者。不确定 Date 如何实现 ICompare,但我经常看到开发人员在值相等时使用传递的 order 参数来打破平局。 hth
      【解决方案3】:

      你是对的 - 你需要实现 IComparable。为此,只需声明您的类:

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

      在 CompareTo 中,您只需实现自定义比较算法(您可以使用 DateTime 对象来执行此操作,但请务必先检查“obj”的类型)。如需更多信息,请参阅herehere

      【讨论】:

      【解决方案4】:
      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))
      );
      

      【讨论】:

        【解决方案5】:

        你可以使用 linq:

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

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            首先,如果 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;
                      });
            

            【讨论】:

              【解决方案8】:

              您的 cTag 类必须实现 IComparable&lt;T&gt; 接口是正确的。然后你就可以在你的名单上打电话给Sort()

              要实现IComparable&lt;T&gt;接口,必须实现CompareTo(T other)方法。最简单的方法是调用要比较的字段的 CompareTo 方法,在您的情况下是日期。

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

              但是,这不会很好地排序,因为这将使用对字符串的经典排序(因为您将日期声明为字符串)。所以我认为最好的办法是重新定义类并声明日期不是字符串,而是日期时间。代码几乎保持不变:

              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) 方法。

              【讨论】:

                【解决方案9】:

                感谢所有快速答复。

                这是我的解决方案:

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

                谢谢

                【讨论】:

                  【解决方案10】:
                  YourVariable.Sort((a, b) => a.amount.CompareTo(b.amount));
                  

                  【讨论】:

                    猜你喜欢
                    • 2012-05-10
                    • 1970-01-01
                    • 2013-03-23
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多