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

Ril*_*n42 20 ruby sorting

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

temp["ninjas"]=36
temp["pirates"]=12
temp["cheese"]=222
temp.sort_by { |key, val| key }
Run Code Online (Sandbox Code Playgroud)

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

Nei*_*ter 32

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

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

试试这个:

temp = Hash[ temp.sort_by { |key, val| key } ]
Run Code Online (Sandbox Code Playgroud)

或者更简洁

temp = temp.sort_by { |key| key }.to_h
Run Code Online (Sandbox Code Playgroud)

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

temp = Hash[ temp.sort_by { |key, val| key.to_s } ] 
Run Code Online (Sandbox Code Playgroud)

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

此外,您可以将密钥转换为Strings以下内容:

temp = Hash[ temp.map { |key, val| [key.to_s, val] }.sort ] 
Run Code Online (Sandbox Code Playgroud)

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


sic*_*ckp 7

sorted_by_key = Hash[original_hash.sort]
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 或 `original_hash.sort.to_h` (4认同)

the*_*Man 6

Ruby 的 Hash 现在可以记住它的插入顺序,但早期的 Ruby < v1.9 不记得了。但是,不要费心对散列进行排序,因为这样做没有任何好处,因为基本上散列是一种随机访问结构。这意味着所有元素都可以随时访问,无论是第一个还是最后一个都没有区别,您可以访问它。

这与 Array 不同,它的作用类似于顺序/文本文件或链或队列,您必须通过迭代来线性访问它,在这一点上,元素的顺序会产生很大的不同。

因此,使用 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]
Run Code Online (Sandbox Code Playgroud)

某些语言甚至不允许您对哈希进行排序,并且通过排序的键列表访问它是按顺序提取元素的唯一方法,因此不养成依赖顺序的习惯可能是个好主意键/值对,而不是依赖于键。

  • 您关于对哈希排序“没有优势”的说法仅在查找情况下才是正确的。如果你想知道*关于*哈希。(例如,创建散列内容的 md5),一致的顺序是相关且必要的。 (3认同)
  • 只是试图完善您所说的“不要费心对哈希进行排序,因为没有优势”的陈述,因为那里的任何菜鸟都可以在学习时扩展他们的思维:)。干杯! (2认同)