使用Linq查找带负数的数字序列的最小值

时间:2015-11-10 08:47:57

标签: c# linq numbers range minimum

以下代码未给出预期的最小值-1。相反,我得到0。 你知道为什么吗?

class MainClass
{
    public static void Main (string[] args)
    {
        string numbers = "-1 0 1 2 3 4 5";
        Console.WriteLine (numbers.Split (' ')[0]);     // output: -1
        string max = numbers.Split(' ').Max();
        string min = numbers.Split(' ').Min();
        Console.WriteLine("{0} {1}", max, min);         // output: "5 0"
    }
}

3 个答案:

答案 0 :(得分:3)

这是一个字符串,所以从字符串中获取最大值与从数字中获取最大值完全不同。例如,如果你有一个如下所示的数组

  

char [] someCharArray = new char [] {'1','12','2'}

在此数组上调用Max()将导致2为2,因为字符串顺序中的“高于”而不是12。

考虑字符串/字符的最大值/最小值您需要考虑字母顺序。如果你有一个字母A-Z的集合,调用Min()将返回A,调用Max()将返回Z.

以数字顺序获取最大值/最小值您需要转换为某种数字类型,如int。 见下文:

string numbers = "-1 0 1 2 3 4 5";
int min = numbers.Split(' ').Select(x => int.Parse(x)).Min();
Console.WriteLine(min); // gives You -1

答案 1 :(得分:2)

我还没有完全定义答案,但似乎是因为-没有考虑到......你可以用CompareOrdinal确认这个

    Console.WriteLine(String.CompareOrdinal("-1", "0"));  // -3 meaning -1 min
    Console.WriteLine(String.Compare("-1", "0"));  // 1 meaning 0 min

无论哪种方式,你都试图比较数字,所以你应该将它们视为数字,这样就不会出现类似的细微之处。

尝试解释......

字符串实现IComparable<string>,因此String.Min使用该实现(请参阅备注)。而后者又使用CompareTo

现在在此方法的注释中

  

字符集包括可忽略的字符。 CompareTo(String)方法在执行区域性敏感比较时不考虑此类字符。例如,如果在.NET Framework 4或更高版本上运行以下代码,则将“animal”“ani-mal”进行比较(使用软连字符,或U + 00AD)表示两个字符串是等价的。

(强调我的)

如你所见。 -被忽略,因此在ascii表中具有较小值的0用于比较

答案 2 :(得分:2)

这种行为有两个原因:

  1. 您正在排序字符串而不是数字。这意味着在幕后,Linq正在使用String.CompareTo()来比较字符串。
  2. String.CompareTo()-有特殊行为,它将其视为HYPHEN,而不是MINUS。 (注意:此连字符不应与具有字符代码U00AD的软连字符混淆。)
  3. 考虑以下代码:

    Console.WriteLine("-1".CompareTo("0")); // 1
    Console.WriteLine("-1".CompareTo("1")); // 1
    Console.WriteLine("-1".CompareTo("2")); // -1
    

    请注意,反直觉地说,“-1”是“0”和“1”,而是“2”之前。

    这解释了为什么在订购字符串时,“-1”既不是最大值也不是最小值。

    Also see the answer to this question for more details.