How many times does Ruby evaluate a loop's enumerated collection?
In Ruby, if I were to loop over a collection, how many times would Ruby evaluate the enumerated collection?
Specifically, I'd like to sort a collection, and loop over the sorted collection. Since I have no need for keeping a copy of the sorted collection around, I figured I'd just write the loop as:
for item in @items.sort{ |a,b| b.created_at <=> a.created_开发者_如何学运维at } do
#do some stuff
end
However, after crafting that lovely bit of code I began to wonder how many times I might be actually calling sort.
Would the above line indeed only sort the collection once? Or will Ruby end up sorting it N times for each item in the collection?
You're calling sort
once.
Except for scoping differences,
for x in xs do
some_stuff
end
is the same as
xs.each do |x|
some_stuff
end
And of course when you do foo.bar(baz)
, foo
is evaluated exactly once, no matter what bar
does.
That's equivalent to sorting the whole collection once, and then iterating it once.
Equivalent to:
@items.sort{ |a,b| b.created_at <=> a.created_at }.each do |item|
# do some stuff
end
Even cleaner and much faster:
@items.sort_by {|a| a.created_at}.reverse
You should pretty much always use sort_by
instead of sort
if you can (and you almost always can), because it evaluates the sort-key function only once per item. And it lets you write half as much comparison code!
精彩评论