我正在尝试在以下结构中对哈希进行分组
{
name: "cardio",
data: [["06:00", 999], ["09:00", 154], ["10:00", 1059], ["11:00", 90]]
}
{
name: "swimming",
data: [["10:00",90 ], ["11:00", 50]]
}
目前这是我的数据。
[{"average_attendance"=>0.999e3, "sum_attendance"=>999, "place_type"=>"cardio", "rounded_hour"=>"06"},
{"average_attendance"=>0.154e3, "sum_attendance"=>154, "place_type"=>"cardio", "rounded_hour"=>"09"},
{"average_attendance"=>0.353e3, "sum_attendance"=>1059, "place_type"=>"cardio", "rounded_hour"=>"10"},
{"average_attendance"=>0.3e2, "sum_attendance"=>90, "place_type"=>"cardio", "rounded_hour"=>"11"},
{"average_attendance"=>0.45e2, "sum_attendance"=>90, "place_type"=>"swimming", "rounded_hour"=>"10"},
{"average_attendance"=>0.5e2, "sum_attendance"=>50, "place_type"=>"swimming", "rounded_hour"=>"11"}]
是否可以减少并对其进行分组以构建[sum_attendance,rounded_hour]数组?
答案 0 :(得分:2)
> attendance_array.group_by{|e| e["place_type"]}.map{|k,v| {"name": k, "data": v.map{|r| [r["sum_attendance"],r["rounded_hour"]]}}}
# [
# {
# :name=>"cardio",
# :data=>[[999, "06"], [154, "09"], [1059, "10"], [90, "11"]]
# },
# {
# :name=>"swimming",
# :data=>[[90, "10"], [50, "11"]]
# }
# ]
首先group
"place_type"
然后将"name"
作为组key
和"data"
作为[sum_attendance, rounded_hour]
<的数组准备哈希/ p>
答案 1 :(得分:1)
arr.each_with_object({}) do |g,h|
k = g["place_type"]
(h[k] ||= []) << ["#{g["rounded_hour"]}:00", g["sum_attendance"]]
end.map { |k,v| { name: k, data: v } }
#=> [{:name=>"cardio", :data=>[["06:00", 999], ["09:00", 154],
# ["10:00", 1059], ["11:00", 90]]},
# {:name=>"swimming", :data=>[["10:00", 90], ["11:00", 50]]}]
这可以写成如下。
arr.each_with_object(Hash.new { |h,k| h[k]=[] }) { |g,h|
h[g["place_type"]] << ["#{g["rounded_hour"]}:00", g["sum_attendance"]] }.
map { |k,v| { name: k, data: v } }
根据我的经验,第一种方法往往会更快一些。
在第二种方法
h = Hash.new { |h,k| h[k]=[] }
创建一个空哈希,以便在h[k]
没有密钥h
时调用k
时执行该块。最初,哈希h
为空,因此对于任何k
,执行h[k]
设置h[k]
等于空数组。如果我们有
h[k] << 1
这导致
h[k] = h[k] << 1
#=> [] << 1
#=> [1]
如果以后我们有(对于相同的k
)
h[k] << 2
我们获得
h[k] = h[k] << 2
#=> [1] << 2
#=> [1,2]
这次不会调用该块,因为h
现在有一个键k
。更准确地说,方法Hash#[]在其参数不是其接收者的密钥h
时调用该块。等式左边的h[k]
是方法Hash#[]=,这就是为什么它也不会调用块。
答案 2 :(得分:0)
您可以使用以下内容:
arr.each_with_object(Hash.new { |k, v| k[v] = {name: v, data: []} }) do |res, exp|
exp[res["place_type"]][:data] << ["#{res["rounded_hour"]}:00", res["sum_attendance"]]
end.values
# [
# {:name => "cardio", :data => [["06:00", 999], ["09:00", 154], ["10:00", 1059], ["11:00", 90]]},
# {:name => "swimming", :data => [["10:00", 90], ["11:00", 50]]}
# ]