2

我有一个结构复杂的红宝石散列,如下所示:

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

4 回答 4

4

reverse反转当前顺序。这意味着您必须先排序并在第二步中反转:

something.sort.reverse.each { ... }

或者你需要明确告诉 Ruby 如何排序:

something.sort_by { |commit_id, _| -commit_id }.each { ... }
于 2017-04-21T14:59:04.603 回答
1

我不确定我是否理解你的要求。如果你想要的是你的散列颠倒了键的顺序是颠倒的,你可以这样做:

reversed = {}
something.keys.reverse.each { |k| reversed[k] = something[k] }
于 2017-04-21T15:05:34.860 回答
1

与其尝试对价值很小的哈希进行排序,不如对键进行排序,然后根据它们的顺序进行提取:

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与键相同的顺序提取值。

使用数组进行排序更有意义,数组通常用作顺序可能很重要的队列或列表。

于 2017-04-21T20:19:36.977 回答
0

好的,有时只需要花时间在 StackOverflow 上写下整个问题。我刚刚了解到.reverse_each实际上做了它所说的:反转哈希。我期待它对哈希进行反向排序。

这就是解决方案:.sort.reverse,如:

something.sort.reverse.each do | key, value |
  p "#{key} #{value[:type]} #{value[:sha]}"
end
于 2017-04-21T14:59:17.630 回答