How can this be? Why in c# "a-0".CompareTo("a0") returns 1?

  • Thread starter Thread starter George Fang
  • Start date Start date
G

George Fang

Hi everyone,

Why in c# "a-0".CompareTo("a0") returns 1? isn't string "a-0" is less than
string "a0"? Could someone help? Thanks, George.
 
Hi everyone,

Why in c# "a-0".CompareTo("a0") returns 1? isn't string "a-0" is less
than string "a0"? Could someone help? Thanks, George.

Sounds like you really wanted to call String.CompareOrdinal().
Alternatively, use the Compare() method and pass
System.Globalization.CompareOptions.Ordinal or CompareOptions.StringSort
to the appropriate overload.

See for more details about different sorting methods:
http://msdn.microsoft.com/en-us/library/system.globalization.compareoptions.aspx

Pete
 
Thank you for the help here. Really, the problem that I have is the sorting
in DatagridView control. It does not sort the string using StringSort option.
How can I get it to do that? My DataGridView is bound to a bindingSource and
the bindingSource is bound to DataTable and the DataTable is filled by
SqlDataAdapter. All this is already complicated enough. Why do we have
another complication with this sorting options that I cannot find a place to
choose? I thought c# would make things easier for me. Thanks,

G.
 
Thank you for the help here. Really, the problem that I have is the
sorting
in DatagridView control. It does not sort the string using StringSort
option.
How can I get it to do that? My DataGridView is bound to a bindingSource
and
the bindingSource is bound to DataTable and the DataTable is filled by
SqlDataAdapter. All this is already complicated enough. Why do we have
another complication with this sorting options that I cannot find a
place to
choose? I thought c# would make things easier for me. Thanks,

There are limits to have much easier any framework can make for you.
Anticipating and serving every single need is not practical. For what
it's worth, the fact that you can describe the basic configuration in a
single paragraph is confirmation that while things may seem complicated to
you, they are FAR simpler than they would have been without a framework
like .NET. :)

As far as your specific problem goes, I think there are at least two
viable solutions:

-- Provide a custom comparator for your rows. It's been awhile since
I've used DataGridView, so I can't comment on specifically how this would
be done. But I'm pretty sure it can be. At the very least, by providing
custom classes for the types on which you want to sort and implementing
IComparable in the types. There may be a way to provide an IComparer
implementation to use.

-- Sort the data earlier on, as part of filling from your
SqlDataAdapter. I'm practically certain you can provide arbitrary
comparison methods there. You may find one convenient approach is to use
a LINQ query, with the Enumerable.OrderBy() method overload that allows
you to pass an IComparer implementation.

Hope that helps.

Pete
 
To set custom sorting for a datagridview control you have to set its
datasource to a dataview object not the table. You set the table to a
dataview object something like this:

DataView dv = new DataView();
dv.Table = dataset1.Tables["tbl1"];
dv.Sort = "columnName";

The default sort is ASC, but you can specify
dv.Sort = "columnName DESC";


Rich
 
Thank you again for the comment here. But I tried both methods. First I tried
to change the comparer for the datagridview (dataGridView1.Sort(myComparer)).
Unfortunately it is data bound and as such, it does not allow me to do that.
I also tried the second option. But the trouble is that when users clicked
the header column twice, the sorting is messed up again! You will see
something like this:

a00
a-00
a01

Framework or not, isn't this annoying enough to bother everyone?
Furthermore, datatable has a locale property so that one can assign a new
CultureInfo. I tried to extend CultureInfo. But unfortunately, I cannot
extend the CompareInfo class. Needless to say, the effort is a waste. Is
there a way to get the sorting correct in data bound datagridview? Thanks
again.

G.
 
Thank you for the message here. But I do not know why we should use DataView.
I can also do the similar thing to bindingSource1 (bindingSource1.Sort =
"columnName DESC"); But the thing is that the sorting on the data bound
datagridview is wrong. We get something like this

a00
a-00
a01

if you click the column header a few times. Somehow there is no way to get
it to use System.Globalization.CompareOptions.StringSort. Of course here I
was hoping that this option would fix it for it appears that the datagridview
uses System.Globalization.CompareOptions.None by default as observed by Peter.

Thanks,

G.
 
a00
a-00
a01
<

Add a hidden column to your datagridview (set its width=0) and here add
the ascii values of your characters and sort on these values.

Rich
 
Isn't this so sad and too bad? Why the string sort with default settings
cannot sort these simple strings? Do I have to create a new class to extend
string class to get the sorting correct for datagridview or for strings? Is
this the case for all the other similar things in c# or the related? Thanks
for the info here.

G.
 
Isn't this so sad and too bad? Why the string sort with default settings
cannot sort these simple strings?

It can. It just happens to not sort them the way you think is the best.

I'm sorry that I don't have enough first-hand experience with the
components you're using to provide a clear, specific answer for how to
implement it the way you want. But you really need to understand that the
sorting behavior that exists isn't broken; it's just different from what
you're used to. In fact, it may be preferable for some users.

One possible option here is to just let the control sort the way it does
now. That may be just as appropriate for some subset of your users as the
sorting method you are trying to get instead.
Do I have to create a new class to extend
string class to get the sorting correct for datagridview or for strings?

System.String is sealed; you can't inherit/extend it. And no, you don't
have to extend it to fix this. You just need to go about the sorting
different.
Is this the case for all the other similar things in c# or the related?

Your question actually has nothing at all to do with C#. It's about the
..NET Framework, and yes...to some extent if you are sorting strings, you
will run into it. Different areas of the Framework provide different
degrees of direct control over the sorting method, so how complicated it
is to get a specific kind of sort will depend on what area of the
Framework you're using.

Pete
 
Peter Duniho said:
It can. It just happens to not sort them the way you think is the best.
I do not know what others think. But in my opinion, this sorting is broken.
I am using the latest visual studio 2008 express with sp1. Do not know if
this is the case for other versions of VS. I would say that string sorting is
so basic and such a problem (default string sort is not what you expect) is a
big surprise for me.

I'm sorry that I don't have enough first-hand experience with the
components you're using to provide a clear, specific answer for how to
implement it the way you want. But you really need to understand that the
sorting behavior that exists isn't broken; it's just different from what
you're used to. In fact, it may be preferable for some users.
I have to say that it is broken, if you have some strings with several - or
hyphens in it, you cannot expect where it would put those strings. It is very
strange. I do not know how it sorts strings with - in it at all. It seems
pretty random.
One possible option here is to just let the control sort the way it does
now. That may be just as appropriate for some subset of your users as the
sorting method you are trying to get instead.

Again, we do not know how the strings are sorted at all.

System.String is sealed; you can't inherit/extend it. And no, you don't
have to extend it to fix this. You just need to go about the sorting
different.

This is perhaps the same case for CompareInfo class. Again it appears things
are getting worse in the area.

Your question actually has nothing at all to do with C#. It's about the
..NET Framework, and yes...to some extent if you are sorting strings, you
will run into it. Different areas of the Framework provide different
degrees of direct control over the sorting method, so how complicated it
is to get a specific kind of sort will depend on what area of the
Framework you're using.

The fact that I just tried out this C# or .net framework as you put to
encounter this is a shock to me.

Thank you for all the info.

G.
 
Peter Duniho said:
It's quite clear that that's your opinion. But you are in the minority.


Again, the sorting behavior is defined by the .NET Framework. It has
nothing to do with Visual Studio, or C#.


That you consider string sorting to be "basic" simply illustrates how
naïvely you're looking at the problem. String sorting is not nearly as
simple a problem as you appear to think it is.


Actually, you can. The sorting is 100% reproducible.


It's not random.


Yes, we do. I quoted MSDN and provided a link where some of the details
can be found. You could research it yourself if you wanted more detail
than that.

As long as you continue to believe that this is a defect in .NET rather
than a feature, you will make poor progress in achieving your goals. You
need to understand the API you're using if you expect to use it
effectively.

So I take your advice and have some look of the link you have. It appears
that - is assigned some random value that we do not really know and that this
"feature" (might be useful in some cases) considered great in all the case by
some there is thus forced on us now such that we have no choice but to accept
it. Is there something wrong here? Thanks for that.

G.
 
So I take your advice and have some look of the link you have. It appears
that - is assigned some random value that we do not really know and that
this
"feature" (might be useful in some cases) considered great in all the
case by
some there is thus forced on us now such that we have no choice but to
accept
it.

It's not being forced on you. You can use different sort methods if you
like.
Is there something wrong here? Thanks for that.

There is nothing wrong here.

Here's an article written awhile ago that discusses a small part of the
issue:
http://blogs.msdn.com/michkap/archive/2004/12/29/344136.aspx

Note that the ability to sort in a locale-specific way (by _other_ than
ordinals) is so important, that Windows has included this feature even in
the unmanaged API since Windows 95/NT 3.51.
http://msdn.microsoft.com/en-us/library/ms647476(VS.85,loband).aspx

Again, this isn't a bug. It's a feature. If you don't like it, don't use
it. The framework is optimized for the common case (i.e. wanting
locale-specific sorting), so yes...if you don't fall into the common case,
sometimes you have extra work to do. C'est la vie.

Pete
 
George said:
Hi everyone,

Why in c# "a-0".CompareTo("a0") returns 1? isn't string "a-0" is less
than string "a0"? Could someone help? Thanks, George.

George,

I have to stick up for you here.

"a-".CompareTo("a0") = -1
"a-0".CompareTo("a0") = 1

I think this looks broken to anyone who has ever done traditional data
processing just about anywhere. The rule you expect is that strings of unequal
length are compared for the shorter length and if that result is unequal then
you are done, otherwise the longer string sorts higher. No character gets
special handling as the comparison is bitwise binary.

Microsoft is free to redefine alphanumeric sorting of course. But this is a
particularly ugly example of why IBM had it right in the first place, IMO.

-rick-
 
[...]
"a-".CompareTo("a0") = -1
"a-0".CompareTo("a0") = 1

I think this looks broken to anyone who has ever done traditional data
processing just about anywhere.

No doubt. But those people are traditionally poorly-equipped to implement
culturally localized program behavior without further training (being one
of those people, I feel confident in that statement...it's required quite
an adjustment for me to abandon many of the ideas I learned 30+ years ago
as computer systems have become more and more complex and supporting
non-English environments has become more and more important).
The rule you expect is that strings of unequal length are compared for
the shorter length and if that result is unequal then you are done,
otherwise the longer string sorts higher. No character gets special
handling as the comparison is bitwise binary.

Microsoft is free to redefine alphanumeric sorting of course. But this
is a particularly ugly example of why IBM had it right in the first
place, IMO.

As character sets get broader and broader, it is simply not possible for a
numeric character code to be the sole determining factor in sorting and
still achieve results that appear culturally normal to users.

And once the comparison method has to take that into account, it makes
sense to apply the culturally-sensitive logic to _all_ cultures, not just
the newly-supported ones.

In the olden days, we only had to deal with ASCII, and users were
accustomed to computers doing things "the computer way" instead of "the
user's way". But, that's not the world we live in now.

All that said, anyone who adamantly feels this is really a problem is free
to file a bug report on Microsoft's Connect web site, or to vote for an
existing bug report. I've already posted references that explain the
"why" of this behavior. Continuing to debate here about how much you hate
the behavior doesn't accomplish anything, except perhaps to create a
ruckus. If you actually care about it, do something that has some chance
of having some positive outcome. Just whining about it isn't useful.

Pete
 
Rick Lones said:
I have to stick up for you here.

"a-".CompareTo("a0") = -1
"a-0".CompareTo("a0") = 1

I think this looks broken to anyone who has ever done traditional data
processing just about anywhere. The rule you expect is that strings of unequal
length are compared for the shorter length and if that result is unequal then
you are done, otherwise the longer string sorts higher. No character gets
special handling as the comparison is bitwise binary.

You're seeing a side effect of something that has confused many people in
Explorer's file name sorting as well. The algorithm apparently tries to
look for names that have numbers with similar prefix, and sorts numerically
by the suffix. This for example, produces this result:

a1
a2
a3
a10
a11
a12
a100
a101
a102

Instead of the raw alpha sort, which would produce this:

a1
a10
a100
a101
a102
a11
a12
a2
a3

Whether that's intuitive or not depends on your point of view.
 
Peter Duniho said:
It's not being forced on you. You can use different sort methods if you
like.


There is nothing wrong here.

Here's an article written awhile ago that discusses a small part of the
issue:
http://blogs.msdn.com/michkap/archive/2004/12/29/344136.aspx

Note that the ability to sort in a locale-specific way (by _other_ than
ordinals) is so important, that Windows has included this feature even in
the unmanaged API since Windows 95/NT 3.51.
http://msdn.microsoft.com/en-us/library/ms647476(VS.85,loband).aspx

Again, this isn't a bug. It's a feature. If you don't like it, don't use
it. The framework is optimized for the common case (i.e. wanting
locale-specific sorting), so yes...if you don't fall into the common case,
sometimes you have extra work to do. C'est la vie.

Well, to me the fact remains that strings are sorted in the default (word
sort) way
when using data bound datagridview control and there is no way to change
this and
it is a feature not a bug. Perhaps that is why people are using all the
other datagrid
controls all the time.

G.
 
[...]
Well, to me the fact remains that strings are sorted in the default
(word sort) way
when using data bound datagridview control and there is no way to change
this and
it is a feature not a bug.

If there were no other way to sort some other way, sure...I'd agree it
would be a bug.

But you CAN sort any way you want. You are making a false claim, and then
using that false claim to justify your characterization of the feature as
a bug.

Just because it's harder to sort some other way doesn't mean you can't do
it. It just means it's more work. As I pointed out before, there's no
way for the framework to include every possibly user scenario. Some
times, you'll just have to do more work. This is one of those times.

Pete
 
Back
Top