Сортировка сложного рубинового хэша работает нормально, но невозможно изменить, что я могу сделать?
У меня есть хеш в ruby со сложной структурой, например:
something = {}
something[1488343493] = { :type => 'tag', :name => 'v1.2', :sha => 'a66fd116e454378794d24c41c193d385be37436f'}
something[1488288253] = { :type => 'pull', :number => '469', :sha => '190ed76e30a5fa7d357e8bfb78adfa687a673635', :title => "Consistent file uploads "}
something[1468674242] = { :type => 'tag', :name => 'v1.1', :sha => '2cf4549d0181ad1d60fbd3bbe132b599a14a8965'}
something[1488457772] = { :type => 'pull', :number => '476', :sha => '5f51fa23ea79bd9b89703cb93a5e38a0f0a338bb', :title => "Extract i18n strings in modals/* "}
something[1488288044] = { :type => 'pull', :number => '470', :sha => 'ab98ec3bf7cbe04f11a17d30ed07e5323b45d5df', :title => "Stop copy & clickthrough from list summaries "}
Это в основном содержит список тегов Github и объединенных запросов на выборку. Я могу легко разобраться с этим .sort
:
something.sort.each do | key, value | # sorts perfectly fine
p "#{key} #{value[:type]} #{value[:sha]}"
end
Но я не хочу отсортированный хеш, а перевернутый хеш. И я полностью озадачен, я не могу полностью изменить это, пытаясь .reverse
это дает NoMethodError
для хэша:
something.reverse.each do | key, value | # undefined method `reverse' for #<Hash:0x0> (NoMethodError)
p "#{key} #{value[:type]} #{value[:sha]}"
end
Пытаясь reverse_each
просто ничего не делает
something.reverse_each do | key, value | # does not reverse at all
p "#{key} #{value[:type]} #{value[:sha]}"
end
То же самое относится и к преобразованию в массив и к обращению, вообще ничего не делает:
gnihtemos = something.to_a.reverse.to_h # does not reverse at all
gnihtemos.each do | key, value |
p "#{key} #{value[:type]} #{value[:sha]}"
end
gnihtemos = Hash[something.to_a.reverse] # does not reverse at all
gnihtemos.each do | key, value |
p "#{key} #{value[:type]} #{value[:sha]}"
end
У меня заканчиваются варианты. Я использую Ruby 2.4.0p0
, Что еще я могу сделать, чтобы повернуть вспять something
?
4 ответа
reverse
меняет текущий порядок Это означает, что вы должны отсортировать сначала и вернуться на второй шаг:
something.sort.reverse.each { ... }
Или вам нужно явно указать Ruby, как сортировать:
something.sort_by { |commit_id, _| -commit_id }.each { ... }
Я не уверен, что понимаю, что вы спрашиваете. Если вам нужен обратный хеш в том смысле, что порядок ключей обратный, вы можете сделать это следующим образом:
reversed = {}
something.keys.reverse.each { |k| reversed[k] = something[k] }
Вместо того, чтобы пытаться сортировать хеш, который имеет очень небольшое значение, вместо этого сортируйте ключи и затем извлекайте их в соответствии с их порядком:
something = {
1488343493 => { :type => 'tag', :name => 'v1.2', :sha => 'a66fd116e454378794d24c41c193d385be37436f'},
1488288253 => { :type => 'pull', :number => '469', :sha => '190ed76e30a5fa7d357e8bfb78adfa687a673635', :title => "Consistent file uploads "},
1468674242 => { :type => 'tag', :name => 'v1.1', :sha => '2cf4549d0181ad1d60fbd3bbe132b599a14a8965'},
1488457772 => { :type => 'pull', :number => '476', :sha => '5f51fa23ea79bd9b89703cb93a5e38a0f0a338bb', :title => "Extract i18n strings in modals/* "},
1488288044 => { :type => 'pull', :number => '470', :sha => 'ab98ec3bf7cbe04f11a17d30ed07e5323b45d5df', :title => "Stop copy & clickthrough from list summaries "},
}
rev_sorted_keys = something.keys.sort.reverse
# => [1488457772, 1488343493, 1488288253, 1488288044, 1468674242]
something.values_at(*rev_sorted_keys)
# => [{:type=>"pull",
# :number=>"476",
# :sha=>"5f51fa23ea79bd9b89703cb93a5e38a0f0a338bb",
# :title=>"Extract i18n strings in modals/* "},
# {:type=>"tag",
# :name=>"v1.2",
# :sha=>"a66fd116e454378794d24c41c193d385be37436f"},
# {:type=>"pull",
# :number=>"469",
# :sha=>"190ed76e30a5fa7d357e8bfb78adfa687a673635",
# :title=>"Consistent file uploads "},
# {:type=>"pull",
# :number=>"470",
# :sha=>"ab98ec3bf7cbe04f11a17d30ed07e5323b45d5df",
# :title=>"Stop copy & clickthrough from list summaries "},
# {:type=>"tag",
# :name=>"v1.1",
# :sha=>"2cf4549d0181ad1d60fbd3bbe132b599a14a8965"}]
Хеш - это структура с произвольным доступом, и сортировка не требуется. Мы можем быстро отсортировать ключи и затем перебрать их, или использовать values_at
извлечь значения в том же порядке, что и ключи.
Сортировка имеет гораздо больше смысла с массивом, который часто используется в качестве очереди или списка, где может быть важен порядок.
Хорошо, иногда просто требуется время, чтобы записать всю проблему в Stackru. Я только что узнал .reverse_each
на самом деле делает то, что говорит: обратный хэш. Я ожидал, что это обратное сортирует хэш.
И это решение: .sort.reverse
, как в:
something.sort.reverse.each do | key, value |
p "#{key} #{value[:type]} #{value[:sha]}"
end