Project

General

Profile

Actions

Bug #12221

closed

Enumerable#sort_by method doesn't work properly when the array has more than 6 elements and you pass nil to the block

Added by lucascaton (Lucas Caton) about 8 years ago. Updated about 8 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]
[ruby-core:74603]

Description

%w(1 2).sort_by { |i| nil }
# => ["1", "2"]

# ...

%w(1 2 3 4 5 6).sort_by { |i| nil }
# => ["1", "2", "3", "4", "5", "6"]

So far, so good...
But look what happens when you have 7 or more elements:

%w(1 2 3 4 5 6 7).sort_by { |i| nil }
# => ["4", "2", "3", "1", "5", "6", "7"]

%w(1 2 3 4 5 6 7 8).sort_by { |i| nil }
# => ["8", "2", "3", "4", "5", "6", "7", "1"]

%w(1 2 3 4 5 6 7 8 9).sort_by { |i| nil }
# => ["9", "2", "3", "4", "5", "6", "7", "8", "1"]

%w(1 2 3 4 5 6 7 8 9 10).sort_by { |i| nil }
# => ["10", "2", "3", "4", "5", "6", "7", "8", "9", "1"]

Updated by sawa (Tsuyoshi Sawada) about 8 years ago

What is wrong with it?

Updated by duerst (Martin Dürst) about 8 years ago

  • Status changed from Open to Rejected

Tsuyoshi Sawada wrote:

What is wrong with it?

To expand on this, you tell Ruby that all the values in the array should be 'valued' at nil. Therefore, they are equal, and any order will be correct. You can exchange nil with any other constant, and get the same result. It looks somewhat surprising in your examples, but the reason that the values get shuffled around is that in general (i.e. when most values are not equal), it leads to an efficient algorithm.

To get what you want, juts use the original array :-). Ruby's sort methods are not stable (i.e., they don't keep the original order if two elements compare as equal). Just do a search for Ruby stable sorting, and you will find a lot of useful explanations.

Actions

Also available in: Atom PDF

Like0
Like0Like0