Линия
state_data.sort_by { |state, counter| state unless state.nil? }
фактически эквивалентно простому state_data.sort
, потому что (state unless state.nil?) == state
в любом случае. Что вы можете сделать, это отделить правильные ключи от клавиш nil
и отсортировать только первые:
state_data.select(&:first).sort + state_data.reject(&:first)
В более общем случае вы также можете определить пользовательскую функцию сравнения следующим образом:
def compare(a, b)
return a.object_id <=> b.object_id unless a || b
return -1 unless b
return 1 unless a
a <=> b
end
state_data.sort { |a, b| compare(a.first, b.first) }
Быстро посмотрев на это, вы увидите, что это довольно уродливо. На самом деле, вам следует переосмыслить свой выбор структуры данных здесь. nil
ключи не кажутся мне очень разумными.
ОБНОВЛЕНИЕ: Глядя на учебник, на который вы ссылаетесь, я понимаю, что в нем содержится много неоптимальной информации. Взгляните на следующий фрагмент "Ruby", например:
ranks = state_data.sort_by{|state, counter| counter}.collect{|state, counter| state}.reverse
state_data = state_data.sort_by{|state, counter| state}
state_data.each do |state, counter|
puts "#{state}:\t#{counter}\t(#{ranks.index(state) + 1})"
end
Вы могли бы написать это более аккуратно и получить тот же результат:
rank = state_data.sort_by(&:last)
state_data.sort.each do |data|
puts "%s:\t%d\t(%d)" % [*data, rank.index(data) + 1]
end
Автор также рекомендует код, подобный
filename = "output/thanks_#{lastname}_#{firstname}.html"
output = File.new(filename, "w")
output.write(custom_letter)
Хотя идиома Ruby будет такой:
filename = "output/thanks_#{lastname}_#{firstname}.html"
File.open(filename, 'w') { |f| f.write(custom_letter) }
Это показывает, что автор не очень подходит для Ruby. Поэтому я не могу рекомендовать этот учебник.