def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
end
Chris wrote:
def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
end
Turns an array into a hash with the web address as a key.
Eric
On 7/25/06, Chris [email protected] wrote:
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails
@webs ||= # if @webs has a vaule do nothing, if it’s nil then put
whatever
is on the right into @webs
Web.find(:all).inject({}){ |webs, web| webs.merge(web.address => web)}
Inject can be a bit tricky. basically It might be easier to abstract
it.
Inject replaces the cumulative with whatever the block evaluates to each
iteration starting with the inject parameter.
[1,2,3].inject({}) { |cumulative, element| cumulative.merge(
element.to_s =>
element ) }
Walking through this one
Element 1
cumulative = {} (the param in inject
element = 1 (The first element to be iterated over)
evaluate block and replace the cumulative
cumulative = cumulative.merge( element.to_s => element) #=> gives {
‘1’ =>
1 }
end iteration
Element 2
cumulative = { ‘1’ => 1 } - The result of the last iteration
element = 2
evaluate block and replace the cumulative
cumulative = cumulative.merge( element.to_s => element) #=> gives {
‘1’ =>
1, ‘2’ => 2 }
end iteration
Element 3
cumulative = { ‘1’ => 1, ‘2’ => 2 } - The result of the last iteration
element = 3
evaluate block and replace the cumulative
cumulative = cumulative.merge( element.to_s => element) #=> gives {
‘1’ =>
1, ‘2’ =>2, ‘3’ => 3 }
end iteration
and so on.
so in the example you would be building a hash of all the web objects of
the
form
web.address => web
Hope that helps
Thanks… that helped
One other thing to note about the code is that it creates quite a few
hashes, 1 initial hash and one for each element in the array. Using the
more abstract example and irb:
irb(main):001:0> [1,2,3].inject({}) { |cumulative, element| puts
cumulative.object_id; cumulative.merge( element.to_s => element ) }
23135864
23135732
23135648
=> {“1”=>1, “2”=>2, “3”=>3}
Here you can see the object_id is different each time, indicating that
cumulative is different on each interation and therefore a new object.
This can be avoided by using the merge! method that will modify the
cumulative object instead of returning a new Hash on each iteration.
irb(main):002:0> [1,2,3].inject({}) { |cumulative, element| puts
cumulative.object_id; cumulative.merge!( element.to_s => element ) }
23116412
23116412
23116412
=> {“1”=>1, “2”=>2, “3”=>3}
russ.
Rick O. wrote:
On 7/25/06, Chris [email protected] wrote:
def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
endFYI in edge rails:
def webs
@webs ||= Web.find(:all).index_by &:address
end
Does the ampersand mean anything, or is it a typo?
Joe
On 7/25/06, Chris [email protected] wrote:
def webs
@webs ||= Web.find(:all).inject({}) { |webs, web|
webs.merge(web.address => web) }
end
FYI in edge rails:
def webs
@webs ||= Web.find(:all).index_by &:address
end
On 7/27/06, Joe [email protected] wrote:
def webs
@webs ||= Web.find(:all).index_by &:address
endDoes the ampersand mean anything, or is it a typo?
Joe
–
Posted via http://www.ruby-forum.com/.
Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails
The ampersand is a Symbol#to_proc. It’s a nice shorcut and basically
says
use the address method on the object passed into the block.
The equivelant is
@webs || Web.find(:all).index_by { |web| web.address }
Does the ampersand mean anything, or is it a typo?
Explanation:
http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc
Regards,
Rimantas
On 27 Jul 2006, at 07:03, Joe wrote:
@webs ||= Web.find(:all).index_by &:address
endDoes the ampersand mean anything, or is it a typo?
It converts the argument to a Proc. You can find everything you need
to know at http://eli.thegreenplace.net/2006/04/18/understanding-ruby-
blocks-procs-and-methods/
(search for “The ampersand (&)” in the article).
Best regards
Peter De Berdt