【问题标题】:LINQ OrderBy or Sort does not order correctly for integer string list?LINQ OrderBy 或 Sort 对整数字符串列表的排序不正确?
【发布时间】:2017-04-17 23:13:11
【问题描述】:

我一直在研究对象的排序,这些对象需要在具有整数值(如“1”、“2”)的字符串上完成。但是 LINQ OrderBy 或 SOrt 本身没有正确排序:

以下代码可以重现我的问题:

            var listStr = new List<string>()
            {
                "1",
                "100",
                "12"
            };

            var sortedList = listStr.OrderBy(x => x);
            var desList = listStr.OrderByDescending(x => x);

这里,SortedList 的顺序是:“1”,“100”,“12”,而 deslist 是“12”,“100”,“12”

我对 C# 排序中的字符串比较方式感到困惑。 我对不工作的原因很感兴趣。

【问题讨论】:

标签: c# .net linq c#-4.0


【解决方案1】:

这个特定的问题一直出现,我很确定 Stack Overflow 上有很好的重复问题涵盖了这个主题。请将问题作为正确的副本关闭,我很乐意删除我的回答作为回应。

与此同时……

问题在于我们人类。

我们看到数字,所以我们用数字思考。对我们来说,1 小于 12,12 小于 100。这里没有问题。

然而,问题是我们正在询问计算机。电脑更挑剔一些。特别是,如果我们要求计算机进行字母排序,它总是会将我们的“事物”作为文本进行排序。这就是问题发生的地方。或者更确切地说,这就是我们的期望不再符合计算机将要做什么的地方。

当计算机被要求对字符串进行排序时,将它们与任何其他字符串排序一样,逐个字符地进行排序。

我们来看看物品:

1
100
12

对我们来说,自然排序顺序是 1、12、100。递增顺序。

到电脑,要求做一个文本排序,自然顺序不一样。

原因是它会一次比较一个字符的字符串。

广义地说,“所有以 1 开头的字符串都将出现在以 2 开头的字符串之前”,这意味着“1”和“100”将出现在“2”之前。这与说“所有以字母 A 开头的单词都在以字母 B 开头的单词之前”完全一样。

然后它会说“所有有 0 的字符串都在有 1、2、3 等最多 9 的字符串之前,包括空格”,因为这是文本排序的完成方式。

换句话说,当你问“整数字符串列表的排序不正确?”时简单的答案是“嗯,不,因为当您按文本排序时,永远不会考虑 integer 部分”。

【讨论】:

  • 感谢@Lasse V. Karlsen。你的回答清楚地说明了我的困惑。
【解决方案2】:
  • 事实:12 小于 100
  • 事实上"12""100"“更大”。

比较数字时,数值用于确定哪个数字更大。

比较字符串时会使用单个字符。不要将字符串作为一个整体来考虑,而是按字符来考虑。所以,"12" 真的是 { '1', '2' } & "100"{ '1', '0', '0' }

在对 "12""100" 进行排序时,比较每个字符中的第一个字符 - 11 - 两者相同,因此我们必须继续处理下一个字符 - 20 - 和2 大于0 所以我们可以立即说"12" 大于"100"。甚至不需要看"100" 中的最终0

【讨论】:

    【解决方案3】:

    您正在执行字典排序(即字母排序),因为您正在排序字符串,而不是整数。

    var listStr = new List<int>()
    {
            1,
            100,
            12
    };
    
    var sortedList = listStr.OrderBy(x => x);
    var desList = listStr.OrderByDescending(x => x);
    

    会做你想做的事。

    编辑解释为什么字典排序是这样排序的: 假设我们有一个 B、BAA 和 BC 的列表。如果按字母顺序对它们进行排序,则会得到 B、BAA 和 BC。当我们将字符串列表作为整数处理时,同样的排序逻辑也适用。 “1”将在前(因为它类似于“B”),“100”将排在第二位(因为它类似于 BAA),“12”将是最后一个(因为它类似于“BC”)。

    【讨论】:

    • 混淆了字符串比较,“12”不是小于“100”吗?
    • 0 在 2 之前。
    【解决方案4】:

    正如 cmets 中所述,由于您将数据存储为字符串,因此它将根据变量的字符串值进行排序。

    按字母顺序来考虑,首先是 bc 或 baa。请注意,本例中的 a=0、b=1、c=2。

    在不更改变量定义的情况下,以下代码应该可以工作。

    var sortedList = listStr.OrderBy(x => int.Parse(x));
    var desList = listStr.OrderByDescending(x => int.Parse(x));
    

    【讨论】:

    • 混淆了字符串比较,“12”不是小于“100”吗?
    • @TrueBeliever 0 在 2 之前
    猜你喜欢
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 2013-04-27
    • 2017-07-15
    • 1970-01-01
    相关资源
    最近更新 更多