【问题标题】:Sort an IList<T> in place [duplicate]对 IList<T> 进行就地排序[重复]
【发布时间】:2015-06-19 18:04:40
【问题描述】:

如果我有一个List&lt;T&gt;,我可以使用例如对它进行排序

myList.Sort((x,y) => x.MyComparisonMethod(y));

如果我有IList&lt;T&gt;,我可以使用

将其排序到一个新列表中
var sortedIList = unsortedIList.OrderBy(x => x.SortingValue);

如何对IList&lt;T&gt; 进行适当的排序?

我正在使用 C# .NET 4.5.1。

【问题讨论】:

  • 为什么要这样做? unsortedIList = unsortedIList.OrderBy(x =&gt; x.SortingValue); 解决不了你的什么情况?
  • " 我可以使用" 将它排序到一个新列表中一个新的列表。你的问题是如何使用List.SortIList&lt;T&gt; 而不是List&lt;T&gt;
  • 您必须创建一个Sort 方法并使用它。以 Mono 使用的其中一个为例。

标签: c# .net list ilist in-place


【解决方案1】:

使用ArrayList.Adapter 作为IList&lt;T&gt; 包装器和您自己的CustomComparer 从一些Comparison 委托开始编写您自己的扩展方法:

public static class IListExtensions
{
    public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
    {
        ArrayList.Adapter((IList)list).Sort(new CustomComparer<T>(comparison));
    }
}

【讨论】:

  • 为什么是-1?没有解释的 -1 的目的是什么?
  • 我其实很喜欢这个,但在框架中找不到CustomComparer。相反,我使用了Comparer&lt;T&gt;.Create(comparison),这似乎符合这里的预期。
【解决方案2】:

"我可以使用"将它排序到一个新列表中,不,不是这样,OrderBy 不会返回一个列表,你必须调用 ToList 来创建一个新列表。你的问题是如何使用List.SortIList&lt;T&gt; 而不是List&lt;T&gt;

你可以为IList&lt;T&gt;写一个扩展方法:

public static IList<T> Sort<T>(this IEnumerable<T> sequence, IComparer<T> comparer = null)
{
    var seqList = sequence as List<T>;
    if (seqList != null)
    {
        seqList.Sort((IComparer<T>)comparer);
        return seqList;
    }

    var seqArray = sequence as T[];
    if (seqArray != null)
    {
        Array.Sort(seqArray, (IComparer<T>)comparer);
        return seqArray;
    }

    return sequence.OrderBy(t => t, (IComparer<T>)comparer).ToList();
}

现在您可以在列表、数组或任何其他类型的序列上使用Sort

IList<string> strings = new[] { "B", "A", "C" };
strings.Sort();

更新:如果您只想要一个用于数组或列表,您可以使用:

public static void Sort<T>(this IList<T> sequence, IComparer<T> comparer = null)
{
    var seqList = sequence as List<T>;
    if (seqList != null)
    {
        seqList.Sort((IComparer<T>)comparer);
        return;
    }

    var seqArray = sequence as T[];
    if (seqArray != null)
    {
        Array.Sort(seqArray, (IComparer<T>)comparer);
    }
}

【讨论】:

  • 这似乎有点令人困惑。它为List&lt;T&gt;T[] 排序,但它为其他任何内容返回一个新列表。
  • @CharlesMager:您可以将参数设为IList&lt;T&gt;,如果您不希望这样做,可以删除return sequence.OrderBy(t =&gt; t, (IComparer&lt;T&gt;)comparer).ToList()。我只是想包括它,因为 OP 已经提到它。这是包罗万象的方法。那么返回值也是多余的。
  • 那么你会遇到IList&lt;T&gt; != List&lt;T&gt; 的“并非所有代码路径都返回值”问题——这确实是问题的症结所在。当IList&lt;T&gt; 可能不是List&lt;T&gt; 时,如何对它进行排序?
  • @CharlesMager:为什么?如果您只想为IList&lt;T&gt; 提供一个,您可以使用void 方法。列表和数组都支持 void 方法Sort。编辑我的答案以显示它。
  • 啊,是的。在那里有点愚蠢......但重点仍然是,如果不是T[]List&lt;T&gt;,它将不会进行任何排序。如果我传入Collection&lt;T&gt;BindingList&lt;T&gt; 等会怎样?
【解决方案3】:

我怀疑您指的是您的OrderBy 无法编译。那是因为它返回一个IOrderedEnumerable,而不是IList,你必须在之后执行ToList()才能将其转换回IList实现:

var sortedIList = unsortedIList.OrderBy(x => x.SortingValue).ToList();

如果你想使用自己的IComparer:

var sortedIList = unsortedIList.OrderBy(x => x.SortingValue, new MyComparer()).ToList();

【讨论】:

  • 这没有回答问题,因为它没有对unsortedIList 就地进行排序
猜你喜欢
  • 2013-10-10
  • 2011-10-03
  • 2016-01-02
  • 2011-12-20
  • 1970-01-01
  • 2011-07-06
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多