在ruby中有一种简单的方法可以通过公共密钥将哈希数组分成多个数组吗?

时间:2017-07-28 16:58:36

标签: arrays ruby

如果我有这样的数组:

[{:x=>1, :y=>a, :z=>i}, {:x=>2, :z=>ii}, {:x=>3, :y=>b, :z=>iii}, {:x=>4, :z=>iv}, {:x=>5, :y=>c, :z=>v}]

是否有一个简单的衬垫可以为每个公共密钥获取数组?:

[[1,2,3,4,5], [a, b, c], [i, ii, iii, iv, v]]

3 个答案:

答案 0 :(得分:3)

如果你有一个指向数组的变量:

arr = [{:x=>1, :y=>a, :z=>i}, {:x=>2, :z=>ii}, {:x=>3, :y=>b, :z=>iii}, {:x=>4, :z=>iv}, {:x=>5, :y=>c, :z=>v}]

然后你可以这样写:

%i{x y z}.map { |key| arr.map { |subarr| subarr[key] }.compact }

答案 1 :(得分:1)

如果您曾尝试将此作为生产代码提交,我认为会有一场拳头大战,但即使您事先不知道密钥,它也能解决问题。

arr = [{:x=>1, :y=>'a', :z=>'i'}, {:x=>2, :z=>'ii'}, {:x=>3, :y=>'b', :z=>'iii'}, {:x=>4, :z=>'iv'}, {:x=>5, :y=>'c', :z=>'v'}]

arr.each_with_object({}) {|h,o| h.each { |k,v| (o[k] ||= []) << v}}.values

答案 2 :(得分:1)

arr = [{:x=>1, :y=>'a', :z=>'i'}, {:x=>2, :z=>'ii'}, {:x=>3, :y=>'b', :z=>'iii'},
       {:x=>4, :z=>'iv'}, {:x=>5, :y=>'c', :z=>'v'}]

keys = arr.flat_map(&:keys).uniq
  #=> [:x, :y, :z]

arr.map { |h| h.values_at(*keys) }.transpose.map(&:compact)
  #=> [[1, 2, 3, 4, 5], ["a", "b", "c"], ["i", "ii", "iii", "iv", "v"]]

在计算keys之后,接下来是三个步骤。

a = arr.map { |h| h.values_at(*keys) }
  #=> [[1, "a", "i"], [2, nil, "ii"], [3, "b", "iii"], [4, nil, "iv"], [5, "c", "v"]]
b = a.transpose
  #=> [[1, 2, 3, 4, 5], ["a", nil, "b", nil, "c"], ["i", "ii", "iii", "iv", "v"]]
b.map(&:compact)
  #=> [[1, 2, 3, 4, 5], ["a", "b", "c"], ["i", "ii", "iii", "iv", "v"]]