【问题标题】:List<> own comparerList<> 自己的比较器
【发布时间】:2011-01-31 08:26:44
【问题描述】:

我有一个列表,其中元素是:

struct element { 
                double priority; 
                int value; 
               }

如何实现我自己的比较器,允许我按优先级排序列表?我尝试使用 SortredList... 但它不允许重复键:(

非常感谢您的帮助!

【问题讨论】:

  • 可能是 c#,因为 泛型/模板语法,c++ 没有任何内建的完全命名为 List 的东西,Java 更喜欢 ArrayList。
  • 绝对是 c#。 c++ 中没有内置列表,java 中没有结构
  • 乔尔和安德烈是对的 - C# ;)

标签: c# list comparator


【解决方案1】:

假设 C# 3 或更高版本:

var sorted = MyList.OrderBy(e => e.priority);

【讨论】:

  • 值得指出的是,这将返回一个新的IEnumerable&lt;&gt;,而不是就地排序现有的List&lt;&gt;
  • 请注意,这不会对列表进行排序,它会在迭代时逐个元素地返回一个有序列表。
  • 我更多的是考虑操作集合和保存结果的排序方法。但是Tnx也为此!我很感激你的帮助:)
【解决方案2】:

您可以使用接受Comparison&lt;T&gt; 委托的Sort overload 执行就地排序:

yourList.Sort((x, y) => x.priority.CompareTo(y.priority));

对于旧版本的 C#,您需要将 lambda 替换为老式委托语法:

yourList.Sort(
    delegate(element x, element y) { return x.priority.CompareTo(y.priority); });

【讨论】:

  • 我很欣赏这个两派方式排序的例子!
  • 我无法让 lamda 建议起作用?我使用的是 3.5,它说无法解析符号 CompareTo
  • Lucifer:可能是因为 priorityelement 结构的私有成员
【解决方案3】:

如果您不能依赖 C# 3 扩展或 Lambda,那么您可以让您的结构实现 IComparable 接口,如下所示:

struct element : IComparable
{
    double priority;
    int value;
    public element(int val, double prio)
    {
        priority = prio;
        value = val;
    }
    #region IComparable Members

    public int CompareTo(object obj)
    {
        // throws exception if type is wrong
        element other = (element)obj;
        return priority.CompareTo(other.priority);
    }

    #endregion
}

这个接口也有typesafe version,但是原理是一样的

在结构或类上实现该接口后,在 List&lt;&gt; 上调用 Sort 方法将“正常工作”

static void Main(string[] args)
{
    Random r = new Random();
    List<element> myList = new List<element>();
    for (int i = 0; i < 10; i++)
        myList.Add(new element(r.Next(), r.NextDouble()));
    // List is now unsorted 
    myList.Sort();
    // List is now sorted by priority
    Console.ReadLine();
}

【讨论】:

  • 不过,即使在 2.0 中,您也可以使用匿名方法。
  • 伟大的实施!感谢您使用示例;)这就是我所需要的! :)
  • 马克:是的,你是对的。不过,这种方法的一个好处是它可以自动适用于有人需要对elements 的集合进行排序的所有地方。
【解决方案4】:

这取决于您是要对列表本身进行排序,还是按排序顺序检索值(不更改列表)。

对列表本身进行排序(假设您有一个名为elementsList&lt;element&gt;):

elements.Sort((x, y) => x.priority.CompareTo(y.priority));
// now elements is sorted

.NET 2.0 等效:

elements.Sort(
    delegate(element x, element y) {
        return x.priority.CompareTo(y.priority);
    }
);

按排序顺序获取值:

var orderedElements = elements.OrderBy(x => x.priority);
// elements remains the same, but orderedElements will retrieve them in order

.NET 2.0 中没有等效的 LINQ,但您可以编写自己的:

public static IEnumerable<T> OrderBy<T>(IEnumerable<T> source, Comparison<T> comparison) {
    List<T> copy = new List<T>(source);
    copy.Sort(comparison);

    foreach (T item in copy)
        yield return item;
}

用法:

Comparison<element> compareByPriority = delegate(element x, element y) {
    return x.priority.CompareTo(y.priority);
};

// unfortunately .NET 2.0 doesn't support extension methods, so this has to be
// expressed as a regular static method
IEnumerable<element> orderedElements = OrderBy(elements, compareByPriority);

【讨论】:

  • 所有答案的好汇编:P
【解决方案5】:

如果你想在不创建新实例的情况下对列表本身进行排序,你可以实现 IComparer,然后使用您的实现实例调用 List.Sort

public class ElementComparer : IComparer<element>
{
    public int Compare(element x, element y)
    {
        throw new NotImplementedException();
    }
}

【讨论】:

  • ...将throw new NotImplementedException(); 替换为return x.priority.CompareTo(y.priority);! :)
猜你喜欢
  • 2014-10-25
  • 1970-01-01
  • 2012-04-27
  • 2011-08-09
  • 1970-01-01
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多