Здесь есть два инструмента, каждый из которых может получить одинаковый результат, но которые имеют разные последствия с точки зрения производительности. sort_by
должен преобразовать каждый элемент один раз и только один раз для сравнения и сортировки. sort
должен запустить этот блок для каждого сравнения , где обычно будет N x log (N) сравнений, выполняемых для каждой операции сортировки. Для больших списков может быть значительно больше операций, чем количество записей в массиве.
Если вы выполняете дорогостоящее преобразование, sort_by
является победителем здесь. Для действительно простых операций sort
иногда лучше, но это субъективный вызов.
Например, два подхода к одному и тому же результату:
array = [ 7, 2, 5, 3, 4, 1, 6 ]
array.sort_by { |a| -a }
# => [7, 6, 5, 4, 3, 2, 1]
# Sort by negated values
array.sort { |a,b| -a <=> -b }
# => [7, 6, 5, 4, 3, 2, 1]
# Reverse the comparison, reverse the sort order
array.sort { |a,b| b <=> a }
Все это допустимые подходы, но преимущество подхода sort_by
становится более очевидным, когда вы минимизируете свой код следующим образом:
# Sort by unary minus (Integer#-@)
array.sort_by(&:-@)
Где в вашем конкретном случае, скажем, вы хотели отсортировать без учета регистра:
collection = [
["NEW JERSEY", "Essex", "Lawyer"],
["Florida", "Palm Beach", "Doctor"],
["New Jersey", "ESSEX", "Firefighter"],
["Pennsylvania", "Bucks", "Doctor"],
["florida", "Broward", "Doctor"],
["Florida", "Palm Beach", "Scientist"]
]
s = collection.sort_by do |e|
e.map(&:downcase)
end
# => [["florida", "Broward", "Doctor"], ["Florida", "Palm Beach", "Doctor"], ... ]
Вызов downcase
для массива является довольно дорогой операцией, поэтому вы хотите выполнить это как можно меньше раз, чтобы избежать создания большого количества дублированных объектов, которые необходимо собирать мусором.