简体   繁体   English

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

[英]Sort items in a nested hash by their key

I have a nested hash with unsorted keys: 我有一个带有未排序键的嵌套哈希:

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

What I'm trying to accomplish is a hash with sorted keys: 我想要完成的是一个带有排序键的哈希:

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

I have experimented with .each method and sort_by 我已经尝试过.each方法和sort_by

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

But I'm getting an error message: TypeError: no implicit conversion of Symbol into Integer 但是我收到一条错误消息:TypeError:没有将Symbol隐式转换为Integer

Any help is greatly appreciated! 任何帮助是极大的赞赏!

PS: I noticed with gem pry the output is already sorted. PS:我注意到gem pry输出已经排序了。 But in IRB it's not. 但在IRB中并非如此。

You can use group_by , and transform_values to transform the values inside each hash, also using sort_by plus to_h : 您可以使用group_bytransform_values转换每个哈希中的值,也可以使用sort_by plus to_h

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

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

You're getting an error because when iterating over a hash, you have to local variables within the block scope to use, the key and its value, you're assigning only one (topic) and trying to get its key, which would be trying to access a key in: 你得到一个错误,因为当迭代一个哈希时,你必须使用块范围内的局部变量,键和它的值,你只分配一个(主题)并试图获取它的键,这将是试图访问密钥:

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

Which isn't possible as is an array. 这是不可能的,因为是一个数组。 You can update your code to: 您可以将代码更新为:

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

But anyway you'll need a way to store the changes or updated and sorted version of that topic values. 但无论如何,您需要一种方法来存储更改或更新和排序的主题值版本。

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

Get keys 获取密钥

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

New sorted hash 新的排序哈希

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"}} 

There can be a better way to do this. 可以有更好的方法来做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM