sort_by
- это уточнение sort
, которое используется примерно так:
people.sort do |person1, person2|
person1 <=> person2
end
Функция sort
уступает блоку, когда ему нужно знать порядок двух вещей, в данном случае, людей. Блок возвращает -1, если левая вещь меньше, чем правильная, 0, если они равны, и 1, если правая вещь больше, чем левая. Оператор космического корабля <=>
обладает замечательным свойством, что он возвращает -1, 0 или +1, именно то, что нужно для сортировки.
Я не смотрел, но велика вероятность, что Ruby использует алгоритм quicksort .
Некоторые умные люди заметили, что мы продолжали делать то же самое с левой стороны оператора космического корабля, что и с правой стороны, и пришли к sort_by
, используемому так:
people.sort_by do |person|
person.name
end
Вместо алгоритма сортировки, дающего два объекта блоку и позволяющего блоку сравнить их, алгоритм отдает один объект блоку. Затем блок возвращает любой атрибут или значение, которые должны использоваться для сортировки. Ruby запоминает значение, возвращаемое блоком для каждого элемента, и сравнивает эти значения, знает, в каком порядке их размещать. Опасно, что вам больше не нужно повторяться.
Ваш случайный код работает, просто "составляя вещи", когда алгоритм сортировки уступает блоку. Вместо того, чтобы возвращать что-то разумное, блок возвращает случайное значение. Это приводит к тому, что алгоритм сортировки сортирует вещи случайным образом.