【问题标题】:Sort a list alphabetically按字母顺序对列表进行排序
【发布时间】:2011-08-06 07:04:30
【问题描述】:

我有以下课程:

class Detail
{
    public Detail()
    {
        _details = new List<string>();
    }
    public IList<string> Details { get { return _details; } }
    private readonly List<string> _details;
}

目前我使用以下方法对班级进行随机排序:

void ShuffleGenericList<T>(IList<T> list)
{
    //generate a Random instance
    var rnd = new Random();
    //get the count of items in the list
    var i = list.Count();
    //do we have a reference type or a value type
    T val = default(T);

    //we will loop through the list backwards
    while (i >= 1)
    {
        //decrement our counter
        i--;
        //grab the next random item from the list
        var nextIndex = rnd.Next(i, list.Count());
        val = list[nextIndex];
        //start swapping values
        list[nextIndex] = list[i];
        list[i] = val;
    }
}

我想做的是按字母顺序对详细信息的内容进行排序。

例如,如果内容如下所示:

[0] a
[1] d
[2] b

我希望能够运行此方法并将它们分类为:

[0] a
[1] b
[2] d

有没有人知道一个简单的方法来做到这一点?请注意,列表中的条目通常少于十个。我可以用 LINQ 做到这一点吗?抱歉,我对 LINQ 不是很熟悉,我刚刚听到一个建议,我可以使用它。

【问题讨论】:

    标签: c# .net linq sorting


    【解决方案1】:

    您只需调用List&lt;T&gt;.Sort就可以就地对列表进行排序:

    list.Sort();
    

    这将使用元素的自然顺序,这在你的情况下很好。

    编辑:请注意,在您的代码中,您需要

    _details.Sort();
    

    因为Sort 方法只定义在List&lt;T&gt;,而不是IList&lt;T&gt;。如果您需要从外部将其排序为List&lt;T&gt;(您不应该将其转换为List&lt;T&gt; 部分是实现细节),您需要做更多的事情工作。

    我不知道 .NET 中有任何基于IList&lt;T&gt; 的就地排序,现在我想起来这有点奇怪。 IList&lt;T&gt; 提供了你需要的一切,所以它可以写成一个扩展方法。如果您想使用其中一种,周围有很多快速排序实现。

    如果您不关心效率低下,您可以随时使用:

    public void Sort<T>(IList<T> list)
    {
        List<T> tmp = new List<T>(list);
        tmp.Sort();
        for (int i = 0; i < tmp.Count; i++)
        {
            list[i] = tmp[i];
        }
    }
    

    换句话说,复制,就地排序,然后将排序后的列表复制回去。


    您可以使用 LINQ 创建一个 列表,其中包含原始值但已排序:

    var sortedList = list.OrderBy(x => x).ToList();
    

    这取决于您想要哪种行为。请注意,您的 shuffle 方法并不理想:

    • 在方法中创建一个新的Random 会遇到一些问题shown here
    • 您可以在循环内声明 val - 您没有使用该默认值
    • 当您知道您正在使用IList&lt;T&gt; 时,使用Count 属性会更惯用
    • 在我看来,for 循环比使用while 循环向后遍历列表更容易理解

    Stack Overflow 上还有其他使用 Fisher-Yates 进行改组的实现 - 搜索一下,您会很快找到。

    【讨论】:

    • 所以如果我想对您在上面创建的列表进行排序,那么我只需要说:sortedList.Sort 吗?
    • 我尝试了排序,但无法使其正常工作。- 我的列表如下所示:IList nD。我试过 nD.Sort() 但它说:无法解析符号“排序”。
    • @Mariko:改用_details.Sort() - 因为_details 被声明为List&lt;string&gt; 而不是IList&lt;string&gt;Sort 仅在 List&lt;T&gt; 上声明,而不在 IList&lt;T&gt; 上声明。
    【解决方案2】:

    有两种方式:

    没有 LINQ:yourList.Sort();

    使用 LINQ:yourList.OrderBy(x =&gt; x).ToList()

    您将在以下位置找到更多信息:https://www.dotnetperls.com/sort

    【讨论】:

    • @Dminox - 我的列表如下所示:IList nD。我试过 nD.Sort() 但它说:无法解析符号“排序”。
    • @Mariko Sort()List&lt;T&gt; 的成员不是 IList&lt;T&gt;。您可能会考虑切换到前者(除非您希望使用不同的 IList&lt;T&gt; 实现。)
    【解决方案3】:

    另一种方式

    _details.Sort((s1, s2) => s1.CompareTo(s2)); 
    

    【讨论】:

    • 这个具有适应按任何对象的属性之一对任何对象进行排序的优点。
    【解决方案4】:

    你应该可以在 LINQ 中使用OrderBy...

    var sortedItems = myList.OrderBy(s => s);
    

    【讨论】:

    • 注意:返回 IEnumerable&lt;T&gt; 并且不是就地排序
    【解决方案5】:

    【讨论】:

    • @goril - 我想使用它,但我得到一个错误。这是我添加到其他评论的内容。希望您能提供帮助 - 我的列表如下所示:IList nD。我试过 nD.Sort() 但它说:无法解析符号“排序”。
    • @Mariko:您使用的接口 IList 不包含 Sort 方法。直接对 List 变量进行排序。换句话说,您可以从示例中对 _details 进行排序,但不能对 Details
    猜你喜欢
    • 2013-05-02
    • 2014-02-08
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多