Project

General

Profile

Actions

Bug #18486

closed

Enumerable#group_by ordering appears to have changed and doesn't match docs.

Added by masukomi@masukomi.org (kay rhodes) 4 months ago. Updated 4 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:107099]

Description

The documentation for Enumerable#group_by suggests the following:

(1..6).group_by { |i| i%3 } #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}

it actually produces this (same values different order). Tested in 2.6.3 and 3.0.2

(1..6).group_by { |i| i%3 } #=> {1=>[1, 4], 2=>[2, 5], 0=>[3, 6]}

as hash table ordering is something people depend on these days I wonder if the reordering of the keys may be more than just a minor documentation bug.

I noticed this in 2.6.3. Assuming the docs matched reality when written this implies we've been living with this for a while. I don't know how long before that this actually changed.

Actions #1

Updated by jeremyevans0 (Jeremy Evans) 4 months ago

This is only a minor documentation issue. I assume the documentation is a left over from pre-1.9, when hashes were unordered. I'll fix it.

Actions #2

Updated by jeremyevans0 (Jeremy Evans) 4 months ago

  • Status changed from Open to Closed

This was already fixed in 1e10099e091

Updated by zverok (Victor Shepelev) 4 months ago

I think it is docs bug.
group_by emerged in Ruby 1.8.7, but my RVM can't install it :(
The earliest I could check was 1.9.3, and it already has order of keys 1, 2, 0.

I think it is a natural reason of keys being in the order they are inserted: the first value for grouping is 1 (1 % 3), so that's why it appears first in the result.

With the preservation of Hash keys order introduced at 1.9, I think that's when the behavior changed :)))
In Ruby 1.8.6, imitation of group_by with inject does the initially documented order:

(1..6).to_a.inject({}) { |r, i| (r[i % 3] ||= []) << i; r }
# => {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}

Updated by matsuda (Akira Matsuda) 4 months ago

group_by emerged in Ruby 1.8.7, but my RVM can't install it :(
The earliest I could check was 1.9.3, and it already has order of keys 1, 2, 0.

off-topic: all-ruby is your friend :) https://github.com/akr/all-ruby

$ docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p (1..6).to_a.inject({}) { |r, i| (r[i % 3] ||= []) << i; r }'
ruby-0.49             -e:1: syntax error
  (snip)
ruby-1.6.8            1..6
                      -e:1: undefined method `inject' for []:Array (NameError)
                  exit 1
ruby-1.8.0            {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
...
ruby-1.8.7-p374       {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
ruby-1.9.0-0          {1=>[1, 4], 2=>[2, 5], 0=>[3, 6]}
...
ruby-3.1.0            {1=>[1, 4], 2=>[2, 5], 0=>[3, 6]}
Actions

Also available in: Atom PDF