【问题标题】:How to sort List<T> in c#如何在 C# 中对 List<T> 进行排序
【发布时间】:2019-12-13 17:39:22
【问题描述】:

我有一个List&lt;Card&gt;,我想对这些卡片进行分类

所以,我正在寻找一种方法来用不同的标准对它们进行排序,比如他们的ID、他们的Name ...

public class Card : IComparer
{
    public string ID;
    public string Name;
    public int CompareId(object firstCard, object secondCard) 
    {
        Card c1 = (Card)firstCard;
        Card c2 = (Card)secondCard;
        return c1.Id.CompareTo(c2.Id);
    }
}

但是,Visual Studio 给我发了一个错误:

'Card' 没有实现接口成员'IComparer&lt;Card&gt;.Compare(Card, Card)'

【问题讨论】:

标签: c# list sorting


【解决方案1】:

您可能希望您的班级 Comparable 而不是 Comparator

public class Card : IComparable<Card>
{
    public string ID;
    public string Name;

    public int CompareTo(Card other) 
    {
        if (null == other)
            return 1;

        // string.Compare is safe when Id is null 
        return string.Compare(this.Id, other.Id);
    }
}

然后

List<Card> myList = ...

myList.Sort();

编辑:如果你想有几个标准可供选择,你必须实现几个比较器作为单独的类,例如

public sealed class CardByIdComparer : IComparer<Card> 
{
    public int Compare(Card x, Card y) 
    {
        if (object.ReferenceEquals(x, y))
            return 0;
        else if (null == x)
            return -1;
        else if (null == y)
            return 1;
        else
            return string.Compare(x.Id, y.Id);
    }
}

并在排序时提供所需的:

List<Card> myList = ...

myList.Sort(new CardByIdComparer());

编辑 2:(灵感来自 spender 的图书馆)。如果您想合并几个比较器为一个(即使用comparer1,在领带上 - comparer2 等)

public sealed class ComparerCombined<T> : IComparer<T> {
  private IComparer<T>[] m_Comparers;

  public ComparerCombined(params IComparer<T>[] comparers) {
    if (null == comparers)
      throw new ArgumentNullException(nameof(comparers));

    m_Comparers = comparers
      .Select(item => item == null ? Comparer<T>.Default : item)
      .Where(item => item != null)
      .Distinct()
      .ToArray();
  }

  public int Compare(T x, T y) {
    if (object.ReferenceEquals(x, y))
      return 0;
    else if (null == x)
      return -1;
    else if (null == y)
      return 1;

    foreach (var comparer in m_Comparers) {
      int result = comparer.Compare(x, y);

      if (result != 0)
        return result;
    }

    return 0;
  }
}

用法:

myList.Sort(new ComparerCombined(
  new CardByIdComparer(),   // Sort By Id
  new CardByNameComparer()  // On tie (equal Id's) sort by name
));

【讨论】:

  • 我写了一个库来帮助处理多个比较标准:github.com/biggyspender/ComparerBuilder ... 然而,鉴于 LINQ 处理得如此优雅,对我来说,它没有出现在这个答案中是显而易见的。
【解决方案2】:

使用 Linq 的最简单方法:

List<Card> objSortedList = objListObject.OrderBy(o=>o.ID).ToList();

List<Card> objSortedList = objListObject.OrderByDescending(o=>o.ID).ToList();

【讨论】:

  • 但可能不使用OrderByColumnName,而是使用例如ID
【解决方案3】:

Good examples for 演示
List&lt;T&gt;.Sort(IComparer &lt;T&gt;) 方法的概念请查看链接。

IComparer&lt;T&gt; 在这个例子中比较方法用于字符串IComparer&lt;T&gt; 但您也可以将其用于 ID(int)。

using System; 
using System.Collections.Generic; 

class GFG : IComparer<string> 
{ 
    public int Compare(string x, string y) 
    { 
        if (x == null || y == null) 
        { 
            return 0; 
        } 

        // "CompareTo()" method 
        return x.CompareTo(y); 

    } 
} 



public class geek 
{ 
    public static void Main() 
    { 
        List<string> list1 = new List<string>(); 

        // list elements 
        list1.Add("C++"); 
        list1.Add("Java"); 
        list1.Add("C"); 
        list1.Add("Python"); 
        list1.Add("HTML"); 
        list1.Add("CSS"); 
        list1.Add("Scala"); 
        list1.Add("Ruby"); 
        list1.Add("Perl"); 

        int range = 4; 

        GFG gg = new GFG(); 

        Console.WriteLine("\nSort a range with comparer:"); 

        // sort the list within a  
        // range of index 1 to 4 
        // where range = 4 
        list1.Sort(1, range, gg); 

        Console.WriteLine("\nBinarySearch and Insert Dart"); 

        // Binary Search and storing  
        // index value to "index" 
        int index = list1.BinarySearch(0, range, 
                                    "Dart", gg); 

        if (index < 0) 
        { 
            list1.Insert(~index, "Dart"); 
            range++; 
        } 

    } 


} 

【讨论】:

  • 不要只发布链接。而是在此处复制完整的答案并解释所描述的方法在问题案例中的工作原理
  • @derHugo 谢谢回复 我下次会小心的
【解决方案4】:

你需要实现IComparer

public int Compare(Card card1, Card card2)
{
   if (card1.ID > card2.ID)
      return 1; //move card1 up
   if (card2.ID  < card1.ID)
      return -1; //move card2 up
  return 0; //do nothing
}

【讨论】:

  • 这与this 答案有何不同?
  • 不一样的,我自己写的,问题很简单,我们想出了相同的实现
  • 还有十二分钟的延迟,但还可以;)
  • 我不是最快的,但仍然在 C# 的美丽世界中航行
猜你喜欢
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 2019-07-02
相关资源
最近更新 更多