Reputation: 21960
The following code doesn't give the expected minimum -1. Instead I get 0. Do you know why?
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"
}
}
Upvotes: 1
Views: 1684
Reputation: 109567
There are two reasons for this behaviour:
String.CompareTo()
to compare the strings.String.CompareTo()
has special behaviour for -
, which it treats as a HYPHEN and not a MINUS. (Note: This hyphen should not be confused with a soft hyphen which has the character code U00AD.)Consider this code:
Console.WriteLine("-1".CompareTo("0")); // 1
Console.WriteLine("-1".CompareTo("1")); // 1
Console.WriteLine("-1".CompareTo("2")); // -1
Notice how, counter-intuitively, the "-1" is AFTER "0" and "1" but BEFORE "2".
This explains why when ordering the strings, the "-1" is neither the max nor the min.
Also see the answer to this question for more details.
Upvotes: 2
Reputation: 43300
I've not fully defined an answer yet but it appears to be because the -
isn't accounted for.. you can confirm this with CompareOrdinal
Console.WriteLine(String.CompareOrdinal("-1", "0")); // -3 meaning -1 min
Console.WriteLine(String.Compare("-1", "0")); // 1 meaning 0 min
Either way, you are trying to compare numbers so you should treat them as numbers so similar subtleties dont appear.
Attempted explanation...
String implements IComparable<string>
so String.Min uses that implementation (see remarks). Which in turn uses CompareTo
,
Now in the notes for this method
Character sets include ignorable characters. The CompareTo(String) method does not consider such characters when it performs a culture-sensitive comparison. For example, if the following code is run on the .NET Framework 4 or later, a comparison of "animal" with "ani-mal" (using a soft hyphen, or U+00AD) indicates that the two strings are equivalent.
(Emphasis mine)
As you see. the -
is ignored hence 0 which has a smaller value in an ascii table is used for the comparison
Upvotes: 2
Reputation: 1661
It's a string so Getting max from string is totally different than getting max from a number. For instance if You would have an array like below
char[] someCharArray = new char[] { '1', '12', '2' }
calling Max() on this array would result with 2 as 2 is "higher" in string order than 12.
Thinking about Max/Min value from string/char You need to think about alphabetical order. If You have a colection of letters A-Z, calling Min() will return A, calling Max() will return Z.
To get Max/Min in numerical order You need to cast to some Number type like int. See below:
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
Upvotes: 2