我有两个这样的数组:
["1","7","8","10"]
和
["1","2","3","6","9","11"]
这些数组表示用户选择的名为Place
的类中的id。我想选择投票最多的地方。我尝试了transpose
,但由于数组的大小不同,无法进行转置。
此示例的预期输出为:
{ "1" => 2, "7" => 1, "8" => 1, "10" => 1, "2" => 1, "3" => 1, "6" => 1, "9" => 1, "11" => 1 }
您可以连接所有数组并计算相同元素的数量,如下所示:
arrays = [["1","7","8","10"], ["1","2","3","6","9","11"]].reduce(:+)
arrays.inject(Hash.new(0)) { |memo, e| memo.update(e => memo[e] + 1) }
# "{ "1" => 2, "7" => 1, "8" => 1, "10" => 1, "2" => 1, "3" => 1, "6" => 1, "9" => 1, "11" => 1 }"
一旦得到这个中间结果,使用max_by
从散列中选择具有最大值的密钥:
arrays = [["1","7","8","10"], ["1","2","3","6","9","11"]].reduce(:+)
arrays.inject(Hash.new(0)) { |memo, e| memo.update(e => memo[e] + 1) }
.max_by { |_, count| count }[0]
#=> "1"
这是另一种方式:
arr = [["1","7","8","10"], ["1","2","3","6","9","11"], ["1","2","7"]]
h = arr.flatten.sort_by(&:to_i).group_by(&:itself)
h.update(h) { |_,v| v.size }
#=> {"1"=>3, "2"=>2, "3"=>1, "6"=>1, "7"=>2, "8"=>1, "9"=>1, "10"=>1, "11"=>1}
步骤:
a = arr.flatten
#=> ["1", "7", "8", "10", "1", "2", "3", "6", "9", "11", "1", "2", "7"]
b = a.sort_by(&:to_i)
#=> ["1", "1", "1", "2", "2", "3", "6", "7", "7", "8", "9", "10", "11"]
h = b.group_by(&:itself)
#=> {"1"=>["1", "1", "1"], "2"=>["2", "2"], "3"=>["3"], "6"=>["6"],
# "7"=>["7", "7"], "8"=>["8"], "9"=>["9"], "10"=>["10"], "11"=>["11"]}
如果你使用的是2.2之前的Ruby版本(当Object#本身被引入时),你需要改为写:
h = b.group_by { |s| s }
最后:
h.update(h) { |_,v| v.size }
#=> {"1"=>["1", "1", "1"], "2"=>["2", "2"], "3"=>["3"], "6"=>["6"],
# "7"=>["7", "7"], "8"=>["8"], "9"=>["9"], "10"=>["10"], "11"=>["11"]}
这使用哈希#更新(又名merge!
)的形式,该形式使用块(此处为{ |_,v| v.size }
)来确定在被合并的两个哈希中存在的密钥的值(在这种情况下是所有密钥)。
更新:Hash#transform_values方法在Ruby v2.4中首次亮相。这使我们能够写出以下内容。
arr.flatten.
sort_by(&:to_i).
group_by(&:itself).
transform_values(&:size)