I've found a bug (in my code) that results from String.CompareTo and binary search because my custom IComparer (for the wrapping type) uses String.Compare(x, y, StringComparison.Ordinal)
.
This is because items.OrderBy(i => i.Name)
(where Name is of type string) used to build the Array to search used the string object itself as the IComparable - and such has different rules:
The comparison uses the current culture to obtain culture-specific information such as casing rules and the alphabetic order of individual characters. For example, a culture could specify that certain combinations of characters be treated as a single character, or uppercase and lowercase characters be compared in a particular way, or that the sorting order of a character depends on the characters that precede or follow it.
For example, {A, b, C} is sorted as [A, b, C]
with the OrderBy-using-Default-String-Compare but should be [b, A, C]
per the Ordinal comparison - since it is not, the binary search is failing.
Now, with the "context" out of the way,
What is the easiest (eg. without implementing a custom IComparer for strings) way to order the objects with string properties the same as with String.Compare(.., StringComparison.Ordinal)
?
Edit: I [just realized I] can, and probably should, just use OrderBy(x => x, theSameComparer)
- but supposing this wasn't possible, how can OrderBy be used with the same results?
The StringComparison enumeration is used to specify whether a string comparison should use the current culture or the invariant culture, word or ordinal sort rules, and be case-sensitive or case-insensitive. When you call a string comparison method such as String.
OrderBy" function utilizes the default comparer for a string. That comparer is not necessarily going to return a sort order based on the ASCII code. For a list of all the different string comparers, see the article on MSDN.
OrdinalIgnoreCase. The StringComparison has the OrdinalIgnoreCase property and treats the characters in the strings to compare as if they were converted to uppercase (using the conventions of the invariant culture) and then it performs a simple byte comparison and it is independent of language.
There is a pre-built StringComparer
that applies StringComparison.Ordinal
- that's StringComparer.Ordinal
:
items.OrderBy(i => i.Name, StringComparer.Ordinal)
You should be able to add StringComparer.Ordinal
directly into your OrderBy
.
string[] content = { "A", "b", "C", "d", "AB", "Ab" };
var ordered = content.OrderBy(o => o, StringComparer.Ordinal);
Then once you iterate through ordered
you would receive the following output:
// Output: A AB Ab C b d
I believe that is what your after.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With