【问题标题】:Is there an easy way in ruby to split an array of hashes into mutiple arrays by common key?ruby 中是否有一种简单的方法可以通过公共键将哈希数组拆分为多个数组?
【发布时间】:2017-07-28 16:58:35
【问题描述】:

如果我有这样的数组:

[{: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]]

【问题讨论】:

  • aii等变量还是方法(或者字符串或者符号,在这种情况下应该写成"a"或者:a)?
  • 当你给出一个例子时,为每个输入值分配一个变量是有帮助的(例如,arr = [{:x=>1,....)。这样,读者可以在答案和 cmets 中引用这些变量 (arr),而无需定义它们。此外,每个人在引用这些对象时都会使用相同的变量。

标签: arrays ruby


【解决方案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}]

那么你可以这样写:

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

【讨论】:

  • 我唯一的建议是将%i{x y z} 替换为从arr 计算的数组,因为arr 的键可以动态确定。
【解决方案2】:

我认为,如果您曾经尝试将其作为生产代码提交,那将会是一场激烈的斗争,但即使您事先不知道密钥,它也能解决问题。

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

【讨论】:

  • 好答案。值得一提的是,这也可以写成arr.each.with.object(Hash.new { |h,k| h[k] = [] }) { |h,o| h.each { |k,v| o[k] &lt;&lt; v }}.values。两者都不是更好。根据我的经验,您的方式往往会更快一些。
【解决方案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'}]

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"]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-28
    • 2020-02-16
    • 2013-02-21
    • 2016-11-04
    • 2017-09-03
    • 2011-10-28
    相关资源
    最近更新 更多