按键对嵌套哈希中的项目进行排序

时间:2019-08-02 09:58:16

标签: ruby-on-rails ruby

我有一个带有未排序键的嵌套哈希:

given =  {
  "lorem" => {
     :AA => "foo",
     :GR => "foo",
     :BB => "foo"
  },
  "ipsum" => {
    :ZZ => "foo",
    :GR => "foo",
  }
}

我要完成的是带有排序键的哈希:

goal =  {
  "ipsum" => {
    :GR => "foo",
    :ZZ => "foo"
  },
  "lorem" => {
     :AA => "foo",
     :BB => "foo",
     :GR => "foo"
  }
}

我已经尝试过.each方法和sort_by

given.each { |topic| topic[:key].sort_by { |k, v| k } }

但是我收到一条错误消息:TypeError:没有将Symbol隐式转换为Integer

非常感谢您的帮助!

PS:我注意到使用gem pry可以对输出进行排序。但是在IRB中却不是。

2 个答案:

答案 0 :(得分:3)

您可以使用group_bytransform_values来转换每个哈希值,还可以使用sort_byto_h

given.transform_values { |value| value.sort.to_h }.sort.to_h

# {"ipsum"=>{:GR=>"foo", :ZZ=>"foo"}, "lorem"=>{:AA=>"foo", :BB=>"foo", :GR=>"foo"}}

之所以会出错,是因为遍历哈希时,您必须在块范围内使用局部变量,键及其值,您仅分配一个(主题)并尝试获取其键,它将尝试访问以下项中的密钥:

["lorem", {:AA=>"foo", :GR=>"foo", :BB=>"foo"}]

不可能像数组那样。您可以将代码更新为:

given.each do |topic, value|
  ...
end

但是无论如何,您都需要一种方法来存储该主题值的更改或更新和排序的版本。

答案 1 :(得分:0)

given_hash =  {"lorem"=>{:AA=>"foo", :GR=>"foo", :BB=>"foo"}, "ipsum"=>{:ZZ=>"foo", :GR=>"foo"}} 

获取密钥

given_hash.keys
=> ["lorem", "ipsum"]

新排序的哈希

new_hash = {}
given_hash.keys.sort.each do |sorted_key|
  new_hash[sorted_key] = given[sorted_key]
end

 => {"ipsum"=>{:ZZ=>"foo", :GR=>"foo"}, "lorem"=>{:AA=>"foo", :GR=>"foo", :BB=>"foo"}} 

可以有一种更好的方法。