Сколько раз Ruby оценивает перечисляемую коллекцию цикла? - PullRequest
0 голосов
/ 09 ноября 2010

Если бы в Ruby я перебрал коллекцию, сколько раз Ruby оценил бы перечисленную коллекцию?

В частности, я бы хотел отсортировать коллекцию и перебрать отсортированную коллекцию. Так как мне не нужно хранить копию отсортированной коллекции, я решил написать цикл так:

for item in @items.sort{ |a,b| b.created_at <=> a.created_at } do
    #do some stuff
end

Однако, после создания этого прекрасного фрагмента кода, я начал задаваться вопросом, сколько раз я мог на самом деле вызывать sort.

Действительно ли вышеприведенная строка отсортирует коллекцию только один раз? Или Руби закончит сортировку N раз для каждого элемента в коллекции?

Ответы [ 3 ]

1 голос
/ 09 ноября 2010

Это эквивалентно сортировке всей коллекции один раз, а затем повторению один раз.

Эквивалентно:

@items.sort{ |a,b| b.created_at <=> a.created_at }.each do |item|
  # do some stuff
end
1 голос
/ 09 ноября 2010

Вы звоните sort один раз.

За исключением различий в области видимости,

for x in xs do
  some_stuff
end

совпадает с

xs.each do |x|
  some_stuff
end

И, конечно, когда вы делаете foo.bar(baz), foo оценивается ровно один раз, независимо от того, что делает bar.

0 голосов
/ 09 ноября 2010

Еще чище и намного быстрее:

@items.sort_by {|a| a.created_at}.reverse

Вы должны почти всегда использовать sort_by вместо sort, если можете (и почти всегда можете), потому что он оценивает ключ сортировкифункционировать только один раз за элемент.И это позволяет вам написать вдвое меньше кода сравнения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...