uniqueness of keys in group_by

C

cribe

Ok, I have a class that extends array but I'm seeing bizarre behavior when I try to do group_by on it.

# first I thought, maybe it uses object_id
"a".object_id == "a".object_id #=> false
["a", "b", "a"].group_by {|i| i} #=> #<OrderedHash {"a"=>["a", "a"], "b"=>["b"]}>

#ok, that's not it. maybe inspect()?
class Klass
def initialize(v)
@value = v
end
def inspect
@value
end
end
arr = []
(0..10).each do |x|
arr << Klass.new(rand(3))
end
arr.group_by {|i| i} #=> #<OrderedHash {2=>[2], 1=>[1], 0=>[0], 2=>[2], 1=>[1], 1=>[1], 2=>[2], 0=>[0], 2=>[2], 2=>[2], 0=>[0]}>

#nope. and yet:
[2, 1, 0, 2, 1, 1, 2, 0, 2, 2, 0].group_by {|i| i} #=>#<OrderedHash {0=>[0, 0, 0], 1=>[1, 1, 1], 2=>[2, 2, 2, 2, 2]}>

# however, if I explicitly call inspect then it works
arr.group_by {|i| i.inspect} #=> #<OrderedHash {0=>[0, 0, 0], 1=>[1, 1, 1], 2=>[2, 2, 2, 2, 2]}>

Any ideas?

(BTW this was all being done in a rails console which is why the results were returning orderedhashes instead of regular hashes but the results are the same in irb anyway)
 
R

Robert Klemme

Ok, I have a class that extends array but I'm seeing bizarre behavior
when I try to do group_by on it.

# first I thought, maybe it uses object_id "a".object_id ==
"a".object_id #=> false ["a", "b", "a"].group_by {|i| i} #=>
#<OrderedHash {"a"=>["a", "a"], "b"=>["b"]}>

#ok, that's not it. maybe inspect()? class Klass def initialize(v)
@value = v end def inspect @value end end arr = [] (0..10).each do
|x| arr<< Klass.new(rand(3)) end arr.group_by {|i| i} #=>
#<OrderedHash {2=>[2], 1=>[1], 0=>[0], 2=>[2], 1=>[1], 1=>[1],
2=>[2], 0=>[0], 2=>[2], 2=>[2], 0=>[0]}>

#nope. and yet: [2, 1, 0, 2, 1, 1, 2, 0, 2, 2, 0].group_by {|i| i}
#=>#<OrderedHash {0=>[0, 0, 0], 1=>[1, 1, 1], 2=>[2, 2, 2, 2, 2]}>

# however, if I explicitly call inspect then it works arr.group_by
{|i| i.inspect} #=> #<OrderedHash {0=>[0, 0, 0], 1=>[1, 1, 1],
2=>[2, 2, 2, 2, 2]}>

Any ideas?

$ ri19 Enumerable#group_by
Enumerable#group_by

(from ruby core)
------------------------------------------------------------------------------
enum.group_by {| obj | block } -> a_hash
enum.group_by -> an_enumerator

------------------------------------------------------------------------------

Returns a hash, which keys are evaluated result from the block, and
values are
arrays of elements in enum corresponding to the key.

If no block is given, an enumerator is returned instead.

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


Hash keys are evaluated based on #hash and #eql? methods.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top