【问题标题】:Ruby - array of hashes group by based on similar hash keyRuby - 基于相似哈希键的哈希数组
【发布时间】:2019-07-22 17:02:07
【问题描述】:

我有一个哈希数组,看起来像:

[{"PROJECT"=>"awesome_project1","VERSION"=>128, "STATUS"=>"not required"},
 {"PROJECT"=>"awesome_project2", "VERSION"=>32, "STATUS"=>"finished"},
 {"PROJECT"=>"awesome_project1", "VERSION"=>64, "STATUS"=>"scheduled"}]

我正在尝试基于其中一个 hask 键合并哈希,因为我知道 group_by 的键可以更改。所以如果我想 group_by "PROJECT" 它看起来像:

[{"PROJECT"=>"awesome_project1","VERSION"=>[128,64], "STATUS"=>["not required","scheduled"]},
 {"PROJECT"=>"awesome_project2", "VERSION"=>32, "STATUS"=>"finished"}]

目前我最接近结果的是使用 group_by。

你知道怎么做吗?

【问题讨论】:

  • 如果你能漂亮地打印你的物品而不是让我们为你做这将是一种善意。

标签: ruby hash


【解决方案1】:

您需要将group_byreduce 值合并。

input.
  group_by { |h| h["PROJECT"] }.
  values.
  map do |v|
    v.reduce({}) do |acc, h|
      acc.merge(h) { |_, v1, v2| v1 == v2 ? v1 : [*v1, *v2] }
    end
  end

#⇒ [{"PROJECT"=>"awesome_project1",
#    "VERSION"=>[128, 64],
#    "STATUS"=>["not required", "scheduled"]},
#   {"PROJECT"=>"awesome_project2",
#    "VERSION"=>32,
#    "STATUS"=>"finished"}]

【讨论】:

  • 不需要values.,因为它后面跟着map
【解决方案2】:

您始终可以通过以下两种方式之一来解决此类问题。第一种是使用Enumerable#group_by,就像@Aleksei(又名mudsie)所做的那样。另一种方法是创建一个散列,其键是进行聚合的值(这里是"PROJEXT" 的值),然后在最后提取该散列的值。这就是我在下面采取的方法。

代码

def doit(arr)
  arr.each_with_object({}) do |g,h|
    h.update(g["PROJECT"]=>(g.merge("STATUS"=>[g["STATUS"]]))) do |_,o1,n1|
      o1.merge(n1) { |k2,o2,n2| k2=="STATUS" ? (o2+n2) : o2 }  
    end
  end.values
end

示例

arr = [
  {"PROJECT"=>"awesome_project1", "VERSION"=>128, "STATUS"=>"not required"},
  {"PROJECT"=>"awesome_project2", "VERSION"=> 32, "STATUS"=>"finished"},
  {"PROJECT"=>"awesome_project1", "VERSION"=> 64, "STATUS"=>"scheduled"}
]

doit arr
  #=> [{"PROJECT"=>"awesome_project1", "VERSION"=>128,
  #       "STATUS"=>["not required", "scheduled"]},
  #    {"PROJECT"=>"awesome_project2", "VERSION"=>32,
  #       "STATUS"=>["finished"]}] 

这不是您要求的返回值。在第二个哈希中你想要"STATUS"=>"finished",而不是"STATUS"=>["finished"]。但是,我故意将值设为数组,因为它几乎总是通过将所有值设为同一类的实例(此处为数组)来节省麻烦。如果必须是"STATUS"=>"finished",请告诉我,我将编辑我的答案。

说明

...正在建设中

【讨论】:

    猜你喜欢
    • 2015-06-13
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 2021-02-05
    • 2017-07-09
    • 1970-01-01
    相关资源
    最近更新 更多