【问题标题】:How do I sort an array of custom classes?如何对一组自定义类进行排序?
【发布时间】:2011-01-29 04:56:33
【问题描述】:

我有一个包含 2 个字符串和 1 个双精度(数量)的类。

类捐赠者

  • 字符串名称
  • 字符串注释
  • 双倍金额

现在我有一个捐赠者数组。
如何按金额排序?

【问题讨论】:

标签: c# .net arrays sorting c#-2.0


【解决方案1】:

如果你实现IComparable<Donator>你可以这样做:

public class Donator :IComparable<Donator>
{
  public string name { get; set; }
  public string comment { get; set; }
  public double amount { get; set; }

  public int CompareTo(Donator other)
  {
     return amount.CompareTo(other.amount);
  }
}

然后,您可以根据需要调用 sort ,例如:

var donors = new List<Donator>();
//add donors
donors.Sort();

.Sort() 调用您为排序实现的CompareTo() 方法。

还有没有 IComparable&lt;T&gt; 的 lambda 替代方案:

var donors = new List<Donator>();
//add donors
donors.Sort((a, b) => a.amount.CompareTo(b.amount));

【讨论】:

  • 实现 IComparer 的类可能是更好的方法。
  • @eschneider - 对于这么简单的事情来说,这几乎总是矫枉过正。那怎么会“更好”?
  • 他们可能需要以各种方式进行排序。 DonorAmountComparer、DonorLastNameComparer、DonorAmountThenLastNameComparer。
  • @eschneider - 这完全不在问题范围内......但即使他们需要,在 lambda 中执行它仍然要紧凑得多。使用比较器的决定是个人喜好,在过去的几年里,我合作过的人都没有选择过。
  • 我不同意,这完全相关。在大多数情况下我同意你的观点,但在你可能需要多个排序顺序的情况下,比较器是最好的方法。
【解决方案2】:

你也可以使用delegates:

class Program
{
    static void Main(string[] args)
    {
        List<Donor> myDonors = new List<Donor>();
        // add stuff to your myDonors list...

        myDonors.Sort(delegate(Donor x, Donor y) { return x.amount.CompareTo(y.amount); });
    }
}

class Donor
{
    public string name;
    public string comment;
    public double amount;
}

【讨论】:

    【解决方案3】:

    通过实现IComparable,然后使用Array.Sort

    public class Donator : IComparable {
        public string name;
        public string comment;
        public double amount;
    
        public int CompareTo(object obj) {
            // throws invalid cast exception if not of type Donator
            Donator otherDonator = (Donator) obj; 
    
            return this.amount.CompareTo(otherDonator.amount);
        }
    }
    
    Donator[] donators;  // this is your array
    Array.Sort(donators); // after this donators is sorted
    

    【讨论】:

    • 如果他不想创建一个新类,他也可以传递一个 lambda 表达式
    • 试过了,真的怎么排序?
    【解决方案4】:

    我总是使用列表泛型,例如

    List<Donator> MyList;
    

    然后我调用 MyList.Sort

    MyList.Sort(delegate (Donator a, Donator b) {
       if (a.Amount < b.Amount) return -1;
       else if (a.Amount > b.Amount) return 1;
       else return 0; );
    

    【讨论】:

    • 这和a.Amount.CompareTo(b.Amount)一样
    • 对。此外,使用我的方法,您可以先添加额外的逻辑来按 Amount 排序,然后,如果 Amount 相同,则 Name 等。对于这种情况,CompareTo 更简单,我的示例仅在您需要更有趣的排序时才有用逻辑。
    • 我认为你错过了一个波浪。
    【解决方案5】:

    你可以使用MyArray.OrderBy(n =&gt; n.Amount) 前提是您已包含 System.Linq 命名空间。

    【讨论】:

    • 我试过 myArray = myArray.orderby... 错误是:Fehler 1 Eine implizite Konvertierung vom Typ "System.Linq.IOrderedEnumerable" in "DongleDonatorSite.Donator[]" ist nicht莫格利希。
    • 使用 .ToArray() 将可枚举转回数组。
    • 您可能希望在末尾添加.ToArray() 或更改您分配结果的变量的类型。顺便说一句,在许多情况下,停止使用数组并开始使用通用列表更为实际(但并非总是在性能成为问题时)。
    • 根据他正在使用.Net 2.0的OP
    【解决方案6】:

    这是一种无需实现接口的排序。这是使用通用列表

        List<Donator> list = new List<Donator>();
        Donator don = new Donator("first", "works", 98.0);
        list.Add(don);
        don = new Donator("first", "works", 100.0);
        list.Add(don);
        don = new Donator("middle", "Yay", 101.1);
        list.Add(don);
        don = new Donator("last", "Last one", 99.9);
        list.Add(don);
        list.Sort(delegate(Donator d1, Donator d2){ return d1.amount.CompareTo(d2.amount); });
    

    【讨论】:

      【解决方案7】:

      另一种方法是创建一个实现IComparer的类,然后在Comparer类中传递一个重载。

      http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx

      这样,您可以为所需的每种特定排序设置不同的类。您可以创建一个按名称、数量或其他排序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-07-11
        • 1970-01-01
        • 2021-01-28
        • 1970-01-01
        • 1970-01-01
        • 2019-05-26
        • 1970-01-01
        相关资源
        最近更新 更多