For all you FPers out there - is this a defined function in any
language’s standard library? And if so, what is it called?
module Enumerable
def collect_by
h = {}
each {|i|
j = yield i
(h[j] ||= []) << i
}
h
# or, as a one-liner
# inject({}) {|c, e| (c[yield e] ||= []) << e; c}
end
end
a = [1,2,3,4,5,6,7,8,9,10]
p a.collect_by {|i| i % 2} #=> {0=>[2, 4, 6, 8, 10], 1=>[1, 3, 5, 7, 9]}
martin
No, it’s not in the standard library. I called it “parition_by”:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/577
I am sure this method was reinvented several times until now, but named
different each time. 
···
On 2003-07-31 02:52:21 +0900, Martin DeMello wrote:
For all you FPers out there - is this a defined function in any
language’s standard library? And if so, what is it called?
–
Who controls the past controls the future. Who controls the present
controls the past.
– George Orwell, 1984
Great idea.
I were just experimenting, when I discovered a glitch in
my understanding of Ruby…
What is the difference between ‘Enumerable1’ and ‘Enumerable’.
Why does the ‘Enumerable’ work and the other not ???
Please enligthen me 
module Enumerable1
def collect_by
h = Hash.new []
each{|i| h[yield(i)].push i}
h
end
end
module Enumerable
def collect_by
h = {}
each{|i| (h[yield(i)] ||= []) << i}
h
end
end
a = (1…10).to_a
p a.collect_by {|i| i % 2}
Enumerable1
#=> {}
Enumerable
#=> {0=>[2, 4, 6, 8, 10], 1=>[1, 3, 5, 7, 9]}
···
–
Simon Strandgaard
Hi –
Great idea.
I were just experimenting, when I discovered a glitch in
my understanding of Ruby…
What is the difference between ‘Enumerable1’ and ‘Enumerable’.
Why does the ‘Enumerable’ work and the other not ???
Please enligthen me 
module Enumerable1
def collect_by
h = Hash.new
each{|i| h[yield(i)].push i}
h
end
end
[…]
Enumerable1
#=> {}
What you’re seeing is a result of the fact that fetching a default
value for a hash does not actually set the key for the hash –
because, by definition, the default value is what you get when you use
a non-existent key, and it doesn’t imply assignment. For example:
irb(main):001:0> h = Hash.new(“hi”)
{}
irb(main):002:0> h[1]
“hi”
irb(main):003:0> h
{}
(Another issue is that the way you’ve written it, h[…] will always
return the same array. But that’s another matter
You can
circumvent that, in 1.8, with: h = Hash.new { } )
David
···
On Thu, 31 Jul 2003, Simon Strandgaard wrote:
–
David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav
Yes, my very favorite 1.8 line:
h = Hash.new { |hash,key| hash[key] = }
···
On Jul 31, dblack@superlink.net wrote:
Hi –
On Thu, 31 Jul 2003, Simon Strandgaard wrote:
Great idea.
I were just experimenting, when I discovered a glitch in
my understanding of Ruby…
What is the difference between ‘Enumerable1’ and ‘Enumerable’.
Why does the ‘Enumerable’ work and the other not ???
Please enligthen me 
module Enumerable1
def collect_by
h = Hash.new
each{|i| h[yield(i)].push i}
h
end
end
[…]
Enumerable1
#=> {}
What you’re seeing is a result of the fact that fetching a default
value for a hash does not actually set the key for the hash –
because, by definition, the default value is what you get when you use
a non-existent key, and it doesn’t imply assignment. For example:
irb(main):001:0> h = Hash.new(“hi”)
{}
irb(main):002:0> h[1]
“hi”
irb(main):003:0> h
{}
(Another issue is that the way you’ve written it, h[…] will always
return the same array. But that’s another matter
You can
circumvent that, in 1.8, with: h = Hash.new { } )
Please enligthen me 
[snip]
(Another issue is that the way you’ve written it, h[…] will always
return the same array. But that’s another matter
You can
circumvent that, in 1.8, with: h = Hash.new { } )
Oh… I luckily forgot about this. Still it won’t work…
What am I doing wrong ?
module Enumerable
def collect_by
h = Hash.new { Array.new } # braces 
each{|i| h[yield(i)].push i}
h
end
end
a = (1…10).to_a
p a.collect_by {|i| i % 2}
#=> {}
···
On Thu, 31 Jul 2003 08:17:44 +0900, dblac wrote:
On Thu, 31 Jul 2003, Simon Strandgaard wrote:
–
Simon Strandgaard
- h[foo] returns a new empty array
- you push something onto that array
- no reference to that array is stored anywhere
- the array disappears into the ether, to get garbage-collected at
a later date
The important thing is, step (1) does not assign anything to the hash.
h remains as {} throughout.
Regards,
Brian.
···
On Thu, Jul 31, 2003 at 08:14:59AM +0900, Simon Strandgaard wrote:
On Thu, 31 Jul 2003 08:17:44 +0900, dblac wrote:
On Thu, 31 Jul 2003, Simon Strandgaard wrote:
Please enligthen me 
[snip]
(Another issue is that the way you’ve written it, h[…] will always
return the same array. But that’s another matter
You can
circumvent that, in 1.8, with: h = Hash.new { } )
Oh… I luckily forgot about this. Still it won’t work…
What am I doing wrong ?
module Enumerable
def collect_by
h = Hash.new { Array.new } # braces 
each{|i| h[yield(i)].push i}
h
end
end
a = (1…10).to_a
p a.collect_by {|i| i % 2}
#=> {}