如何按键按字母顺序对Ruby Hash进行排序

我试图按键按字母顺序排序哈希,但我似乎无法找到一种方法来创建自己的排序类。 我发现下面的代码按值排序,如果它是一个整数,我试图修改它,但没有任何运气。

temp["ninjas"]=36 temp["pirates"]=12 temp["cheese"]=222 temp.sort_by { |key, val| key } 

我的目标是按键排序Hash然后输出值。 我将不得不使用不同的哈希顺序多次执行此操作,但值相同。

假设您希望输出是一个散列,它将按排序顺序迭代键,那么您就在那里。 Hash#sort_by返回一个Array Array ,内部数组都是两个元素。

Ruby的Hash有一个可以使用此输出的构造函数。

试试这个:

 temp = Hash[ temp.sort_by { |key, val| key } ] 

如果您的散列具有混合键类型,则这将不起作用(例如,Ruby不会在StringSymbol之间自动排序),并且您将收到错误消息,例如Symbol与String的比较失败(ArgumentError) 。 如果是这样,你可以改变上面的

 temp = Hash[ temp.sort_by { |key, val| key.to_s } ] 

解决这个问题。 但是请注意,密钥仍将保留其原始类型,这可能会导致后续代码中的假设出现问题。 此外,大多数内置类都支持.to_s方法,因此您可能会从中获得不需要的结果(例如数字键或其他意外类型的意外排序顺序)。

此外 ,您可以使用以下内容将键转换为Strings

 temp = Hash[ temp.map { |key, val| [key.to_s, val] }.sort ] 

。 。 。 虽然这种方法会丢失有关原始密钥类型的信息,但却无法可靠地返回原始数据。

 sorted_by_key = Hash[original_hash.sort] 

将通过按键按字母顺序插入original_hash的键/值来创建新的哈希值。 Ruby 2.x哈希记住它们的插入顺序,因此如果你枚举它或输出它,这个新哈希将按键排序。

如果以非字母顺序插入更多元素,则当然不会这样。

此外,这假设原始哈希键都是可排序/可比较的。

Ruby的Hash现在记得它的插入顺序,但早期的Rubies

这与一个像顺序/文本文件或链或队列一样的数组不同,你必须通过遍历它来线性访问它,在那时,元素的顺序会产生很大的不同。

因此,使用Hash,获取密钥,对它们进行排序,然后迭代密钥列表或使用values_at一次检索所有值。 例如:

 hash = { 'z' => 9, 'a' => 1 } sorted_keys = hash.keys.sort # => ["a", "z"] sorted_keys.each do |k| puts hash[k] end # >> 1 # >> 9 hash.values_at(*sorted_keys) # => [1, 9] 

有些语言甚至不会让你对哈希进行排序,并且通过排序的键列表访问它是提取顺序中元素的唯一方法,所以不要养成依赖于顺序的习惯。键/值对,而是依赖于键。

您可以创建一个新的空哈希来保存已排序的哈希数据。 迭代返回的数组并将数据加载到新哈希中以保存已排序的哈希数据。

 temp = {} temp["ninjas"]=36 temp["pirates"]=12 temp["cheese"]=222 temp = temp.sort_by { |key, val| key } temp_sorted = {} temp.each { |sub_arr| temp_sorted[sub_arr[0]] = sub_arr[1] } temp = temp_sorted 

temp现在等于{“cheese”=> 222,“ninjas”=> 36,“pirates”=> 12}