Arrays 对复杂的ruby哈希进行排序工作正常,但它';It’不可能逆转,我该怎么办?

Arrays 对复杂的ruby哈希进行排序工作正常,但它';It’不可能逆转,我该怎么办?,arrays,ruby,sorting,reverse,ruby-hash,Arrays,Ruby,Sorting,Reverse,Ruby Hash,我在ruby中有一个具有复杂结构的哈希,如下所示: something = {} something[1488343493] = { :type => 'tag', :name => 'v1.2', :sha => 'a66fd116e454378794d24c41c193d385be37436f'} something[1488288253] = { :type => 'pull', :number => '469', :sha => '190ed76e30

我在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标记列表和合并的pull请求。我可以使用
轻松对其进行排序。排序

something.sort.each do | key, value | # sorts perfectly fine
  p "#{key} #{value[:type]} #{value[:sha]}"
end
但我不想要排序的散列,而是反向散列。我完全困惑于我根本无法反转它,试图
。反转
它为散列提供
NoMethodError

something.reverse.each do | key, value | # undefined method `reverse' for #<Hash:0x0> (NoMethodError)
  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.sort.reverse.each { ... }
或者您需要明确告诉Ruby如何排序:

something.sort_by { |commit_id, _| -commit_id }.each { ... }

好吧,有时候只需要花点时间在StackOverflow上写下整个问题。我刚刚学习了
。reverse\u each
实际上是按照它说的做的:反转散列。我希望它能对散列进行反向排序

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

something.sort.reverse.each do | key, value |
  p "#{key} #{value[:type]} #{value[:sha]}"
end

我不确定我是否理解你的要求。如果您想要的是在密钥顺序颠倒的意义上颠倒散列,您可以这样做:

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\u at
以与键相同的顺序提取值


排序对于数组更有意义,数组通常用作队列或列表,其中顺序可能很重要。

也许您需要
某种东西。invert
,它生成一个键和值颠倒的哈希。看见在这里,键将变成散列。我说“也许”是因为我不明白这个问题。你为什么要对哈希进行排序?这没有什么好处。取而代之的是,获取键,对它们进行排序,然后按顺序提取值。如果您想颠倒顺序,那么使用
reverse
。在ruby中,我们使用
each_with_object
something.keys.reverse.each_with_object{k,acc | acc.merge!({k=>something[k]})
。感谢eric duminil,代码已更新@mudasobwa您不能在数组中使用每个带对象的数组(#keys返回一个数组)。@yoones:为什么您认为
每个带对象的数组都没有定义?尝试
[]方法(:each_with_object)
@EricDuminil事实上,
each_with_object
在类实现
each
并包含
可枚举的混入时是免费授予的。你说得对,我的错。仍然@mudasobwa我不认为在这种情况下使用它有什么意义?
reverse
没有为散列定义。因此,
.reverse
不会反转散列。不过,它反转了由
散列#排序
返回的数组。我认为这是因为您的回答清楚地表明问题根本不清楚。;)嗯,我投了a)这个答案是不正确的(它说,
Hash#reverse
做了它的工作,而这个方法甚至不存在,正如@EricDuminil所指出的)和b)这个答案与被接受的答案相比没有带来任何附加值。我敢说,
something.sort_by{k,\u124;-k}
something.sort_by{| commit_id,{u124;-commit_id}
更具可读性。使用
排序
和一个块,
a
b
交换可能不是很明显。同意。我不知道为什么,但我总是忘记了
排序
的优点。。。
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"}]