首先按值排序哈希,然后按键排序

时间:2018-04-17 19:19:43

标签: ruby sorting hash

我有一个哈希[原文如此]:

[
  ["a", 1], 
  ["b", 1], 
  ["d", 1], 
  ["k", 1], 
  ["r", 1], 
  ["f", 2], 
  ["j", 2], 
  ["o", 2], 
  ["i", 3], 
  ["s", 3]
]

我希望输出按从最小到最大的数字排序,然后按字母顺序依次排序:

[
  ["r", 1], 
  ["k", 1], 
  ["d", 1], 
  ["b", 1], 
  ["a", 1], 
  ["o", 2], 
  ["j", 2], 
  ["f", 2], 
  ["s", 3], 
  ["i", 3]
]

有办法做到这一点吗?

这是我的代码:

def letter_counts(word)
  my_hash = Hash.new(0)
  word.split("").each{|word| my_hash[word] += 1}
  my_hash.sort_by{|key,value| [value, key]}
end

3 个答案:

答案 0 :(得分:4)

按照每个最后一个元素(整数元素)对数组中的元素进行分组,通过按第一个元素对每个组进行排序来映射它们,然后反转:

def hsort(array)
  array.group_by(&:last).flat_map { |_, v| v.sort_by(&:first).reverse }
end

p hsort([["a", 1], ["b", 1], ["d", 1], ["k", 1], ["r", 1], ["f", 2], ["j", 2], ["o", 2], ["i", 3], ["s", 3]])
# [["r", 1], ["k", 1], ["d", 1], ["b", 1], ["a", 1], ["o", 2], ["j", 2], ["f", 2], ["s", 3], ["i", 3]]
p hsort([["e", 1], ["b", 1], ["d", 1], ["k", 1], ["r", 1], ["f", 2], ["j", 2], ["o", 2], ["i", 3], ["s", 3]])
# [["r", 1], ["k", 1], ["e", 1], ["d", 1], ["b", 1], ["o", 2], ["j", 2], ["f", 2], ["s", 3], ["i", 3]]

答案 1 :(得分:4)

h = {"b"=>1, "j"=>2, "r"=>1, "o"=>2, "k"=>1, "a"=>1, "s"=>3, "i"=>3, "f"=>2, "d"=>1}

h.max_by(h.size) { |k,v| [-v,k] }
  #=> [["r", 1], ["k", 1], ["d", 1], ["b", 1], ["a", 1],
  #    ["o", 2], ["j", 2], ["f", 2],
  #    ["s", 3], ["i", 3]]

这使用带有参数的Enumerable#max_by形式,这里是哈希中键值对的数量。请注意,max_by(以及min_bymaxmin)首先被允许在Ruby v2.2中拥有参数。

答案 2 :(得分:1)

[
  ["a", 1], 
  ["b", 1], 
  ["d", 1], 
  ["k", 1], 
  ["r", 1], 
  ["f", 2], 
  ["j", 2], 
  ["o", 2], 
  ["i", 3], 
  ["s", 3]
]
.sort_by{|k, v| [v, -k.ord]}

输出:

[
  ["r", 1],
  ["k", 1],
  ["d", 1],
  ["b", 1],
  ["a", 1],
  ["o", 2],
  ["j", 2],
  ["f", 2],
  ["s", 3],
  ["i", 3]
]