如果我有这样的数组:
[{: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]]
答案 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"]]