I am trying to sort a Hash alphabetically by key, but I can't seem to find a way to do it without creating my own Sorting class. I found the code below to sort by value if it's an integer and I am trying to modify it but not having any luck.
我试图按键按字母顺序排序哈希,但我似乎无法找到一种方法来创建自己的排序类。我发现下面的代码按值排序,如果它是一个整数,我试图修改它,但没有任何运气。
temp["ninjas"]=36
temp["pirates"]=12
temp["cheese"]=222
temp.sort_by { |key, val| key }
My goal is to order the Hash by key then output the values. I will have to do this multiple times with different hash orders but the same values.
我的目标是按键排序Hash然后输出值。我将不得不使用不同的哈希顺序多次执行此操作,但值相同。
4 个解决方案
#1
22
Assuming you want the output to be a hash which will iterate through keys in sorted order, then you are nearly there. Hash#sort_by
returns an Array
of Array
s, and the inner arrays are all two elements.
假设您希望输出是一个散列,它将按排序顺序迭代键,那么您就在那里。 Hash#sort_by返回一个数组数组,内部数组都是两个元素。
Ruby's Hash
has a constructor that can consume this output.
Ruby的Hash有一个可以使用此输出的构造函数。
Try this:
尝试这个:
temp = Hash[ temp.sort_by { |key, val| key } ]
If your hash has mixed key types, this will not work (Ruby will not automatically sort between String
s and Symbol
s for instance) and you will get an error message like comparison of Symbol with String failed (ArgumentError). If so, you could alter the above to
如果您的散列具有混合键类型,则这将不起作用(例如,Ruby不会自动在字符串和符号之间进行排序),并且您将收到错误消息,例如Symbol与String的比较失败(ArgumentError)。如果是这样,你可以改变上面的
temp = Hash[ temp.sort_by { |key, val| key.to_s } ]
to work around the issue. However be warned that the keys will still retain their original types which could cause problems with assumptions in later code. Also, most built-in classes support a .to_s
method, so you may get unwanted results from that (such as unexpected sort order for numeric keys, or other unexpected types).
解决这个问题。但是请注意,密钥仍将保留其原始类型,这可能会导致后续代码中的假设出现问题。此外,大多数内置类都支持.to_s方法,因此您可能会从中获得不需要的结果(例如数字键或其他意外类型的意外排序顺序)。
You could, in addition, convert the keys to Strings
with something like this:
此外,您可以使用以下内容将键转换为字符串:
temp = Hash[ temp.map { |key, val| [key.to_s, val] }.sort ]
. . . although this approach would lose information about the type of the original key making it impossible to refer back to the original data reliably.
。 。 。虽然这种方法会丢失有关原始密钥类型的信息,但却无法可靠地返回原始数据。
#2
6
sorted_by_key = Hash[original_hash.sort]
will create a new Hash by inserting the key/values of original_hash
alphabetically by key. Ruby 2.x hashes remember their insertion order, so this new hash will appear sorted by key if you enumerate it or output it.
将通过按键按字母顺序插入original_hash的键/值来创建新的哈希值。 Ruby 2.x哈希记住它们的插入顺序,因此如果你枚举它或输出它,这个新哈希将按键排序。
If you insert more elements in a non-alphabetical order, this won't hold of course.
如果以非字母顺序插入更多元素,则当然不会这样。
Also, this assumes the original hash keys are all sortable/comparable.
此外,这假设原始哈希键都是可排序/可比较的。
#3
4
Ruby's Hash remembers its insertion order now days, but earlier Rubies < v1.9 don't. But, don't bother sorting a hash as there is no advantage to doing so because basically a Hash is a random-access structure. That means the elements are all accessible at any time and it won't make a difference whether one is first or last, you can access it just the same.
Ruby的Hash现在记得它的插入顺序,但早期的Rubies
That's unlike an Array which acts like a sequential/text file or a chain or a queue and you have to access it linearly by iterating over it, which, at that point, the order of the elements makes a big difference.
这与一个像顺序/文本文件或链或队列一样的数组不同,你必须通过遍历它来线性访问它,在那时,元素的顺序会产生很大的不同。
So, with a Hash, get the keys, sort them, and either iterate over the list of keys or use values_at
to retrieve all the values at once. For instance:
因此,使用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]
Some languages won't even let you sort the hash, and accessing it via a sorted list of keys is the only way to extract the elements in an order, so it's probably a good idea to not get in the habit of relying on order of the key/value pairs, and instead rely on the keys.
有些语言甚至不会让你对哈希进行排序,并且通过排序的键列表访问它是提取顺序中元素的唯一方法,所以不要养成依赖于顺序的习惯。键/值对,而是依赖于键。
#4
0
You can create a new empty hash to hold the sorted hash data. Iterate through the returned array and load the data into the new hash to hold the sorted hash data.
您可以创建一个新的空哈希来保存已排序的哈希数据。迭代返回的数组并将数据加载到新哈希中以保存已排序的哈希数据。
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 now equals {"cheese"=>222, "ninjas"=>36, "pirates"=>12}
temp现在等于{“cheese”=> 222,“ninjas”=> 36,“pirates”=> 12}
#1
22
Assuming you want the output to be a hash which will iterate through keys in sorted order, then you are nearly there. Hash#sort_by
returns an Array
of Array
s, and the inner arrays are all two elements.
假设您希望输出是一个散列,它将按排序顺序迭代键,那么您就在那里。 Hash#sort_by返回一个数组数组,内部数组都是两个元素。
Ruby's Hash
has a constructor that can consume this output.
Ruby的Hash有一个可以使用此输出的构造函数。
Try this:
尝试这个:
temp = Hash[ temp.sort_by { |key, val| key } ]
If your hash has mixed key types, this will not work (Ruby will not automatically sort between String
s and Symbol
s for instance) and you will get an error message like comparison of Symbol with String failed (ArgumentError). If so, you could alter the above to
如果您的散列具有混合键类型,则这将不起作用(例如,Ruby不会自动在字符串和符号之间进行排序),并且您将收到错误消息,例如Symbol与String的比较失败(ArgumentError)。如果是这样,你可以改变上面的
temp = Hash[ temp.sort_by { |key, val| key.to_s } ]
to work around the issue. However be warned that the keys will still retain their original types which could cause problems with assumptions in later code. Also, most built-in classes support a .to_s
method, so you may get unwanted results from that (such as unexpected sort order for numeric keys, or other unexpected types).
解决这个问题。但是请注意,密钥仍将保留其原始类型,这可能会导致后续代码中的假设出现问题。此外,大多数内置类都支持.to_s方法,因此您可能会从中获得不需要的结果(例如数字键或其他意外类型的意外排序顺序)。
You could, in addition, convert the keys to Strings
with something like this:
此外,您可以使用以下内容将键转换为字符串:
temp = Hash[ temp.map { |key, val| [key.to_s, val] }.sort ]
. . . although this approach would lose information about the type of the original key making it impossible to refer back to the original data reliably.
。 。 。虽然这种方法会丢失有关原始密钥类型的信息,但却无法可靠地返回原始数据。
#2
6
sorted_by_key = Hash[original_hash.sort]
will create a new Hash by inserting the key/values of original_hash
alphabetically by key. Ruby 2.x hashes remember their insertion order, so this new hash will appear sorted by key if you enumerate it or output it.
将通过按键按字母顺序插入original_hash的键/值来创建新的哈希值。 Ruby 2.x哈希记住它们的插入顺序,因此如果你枚举它或输出它,这个新哈希将按键排序。
If you insert more elements in a non-alphabetical order, this won't hold of course.
如果以非字母顺序插入更多元素,则当然不会这样。
Also, this assumes the original hash keys are all sortable/comparable.
此外,这假设原始哈希键都是可排序/可比较的。
#3
4
Ruby's Hash remembers its insertion order now days, but earlier Rubies < v1.9 don't. But, don't bother sorting a hash as there is no advantage to doing so because basically a Hash is a random-access structure. That means the elements are all accessible at any time and it won't make a difference whether one is first or last, you can access it just the same.
Ruby的Hash现在记得它的插入顺序,但早期的Rubies
That's unlike an Array which acts like a sequential/text file or a chain or a queue and you have to access it linearly by iterating over it, which, at that point, the order of the elements makes a big difference.
这与一个像顺序/文本文件或链或队列一样的数组不同,你必须通过遍历它来线性访问它,在那时,元素的顺序会产生很大的不同。
So, with a Hash, get the keys, sort them, and either iterate over the list of keys or use values_at
to retrieve all the values at once. For instance:
因此,使用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]
Some languages won't even let you sort the hash, and accessing it via a sorted list of keys is the only way to extract the elements in an order, so it's probably a good idea to not get in the habit of relying on order of the key/value pairs, and instead rely on the keys.
有些语言甚至不会让你对哈希进行排序,并且通过排序的键列表访问它是提取顺序中元素的唯一方法,所以不要养成依赖于顺序的习惯。键/值对,而是依赖于键。
#4
0
You can create a new empty hash to hold the sorted hash data. Iterate through the returned array and load the data into the new hash to hold the sorted hash data.
您可以创建一个新的空哈希来保存已排序的哈希数据。迭代返回的数组并将数据加载到新哈希中以保存已排序的哈希数据。
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 now equals {"cheese"=>222, "ninjas"=>36, "pirates"=>12}
temp现在等于{“cheese”=> 222,“ninjas”=> 36,“pirates”=> 12}