Ruby中的MapReduce数组



我有两个这样的数组:

["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)

相关内容

  • 没有找到相关文章

最新更新