我需要按键对哈希进行分组并连接值。例如,给定此哈希:
[
{"name": "FT002", "data": {"2017-11-01": 1392.0}},
{"name": "FT004", "data": {"2017-11-01": 4091.0}},
{"name": "FT002", "data": {"2017-12-01": 1279.0}},
{"name": "FT004", "data": {"2017-12-01": 3249.0}}
]
我想生成这个哈希:
[
{"name": "FT002", "data": {"2017-11-01": 1392.0, "2017-12-01": 1279.0}},
{"name": "FT004", "data": {"2017-11-01": 4091.0, "2017-12-01": 3249.0}}
]
任何帮助都将不胜感激。
我尝试了inject
,group_by
和merge
的各种迭代,但似乎无法获得正确的结果。
答案 0 :(得分:1)
您可以在三个简短的单行中完成此操作,首先生成哈希映射名称到数据,然后生成所需的结构:
data = [
{"name":"FT002","data":{"2017-11-01":1392.0}},
{"name":"FT004","data":{"2017-11-01":4091.0}},
{"name":"FT002","data":{"2017-12-01":1279.0}},
{"name":"FT004","data":{"2017-12-01":3249.0}}
]
hash = Hash.new { |hash,key| hash[key] = {} }
data.each { |name:, data:| hash[name].merge!(data) }
hash = hash.map { |k,v| { name: k, data: v } }
答案 1 :(得分:1)
data.group_by { |h| h[:name] }.map do |k,arr|
{ name: k, data: arr.each_with_object({}) { |g,h| h.update(g[:data]) } }
end
#=> [{:name=>"FT002", :data=>{:"2017-11-01"=>1392.0, :"2017-12-01"=>1279.0}},
# {:name=>"FT004", :data=>{:"2017-11-01"=>4091.0, :"2017-12-01"=>3249.0}}]
第一步是使用Enumerable#group_by生成以下哈希值。
data.group_by { |h| h[:name] }
#=> {"FT002"=>[
# {:name=>"FT002", :data=>{:"2017-11-01"=>1392.0}},
# {:name=>"FT002", :data=>{:"2017-12-01"=>1279.0}}
# ],
# "FT004"=>[
# {:name=>"FT004", :data=>{:"2017-11-01"=>4091.0}},
# {:name=>"FT004", :data=>{:"2017-12-01"=>3249.0}}
# ]
# }
第二步是简单地操纵此哈希的键和值。请参阅Hash#update(又名merge!
)。
第二步的替代方法如下。
data.group_by { |h| h[:name] }.map do |k,arr|
{ name: k, data: arr.map { |g| g[:data].flatten }.to_h }
end
请注意,这使用的是Hash#flatten,而不是Array#flatten。
答案 2 :(得分:-1)
这应该会产生您正在寻找的结果:
data = [
{"name":"FT002","data":{"2017-11-01":1392.0}},
{"name":"FT004","data":{"2017-11-01":4091.0}},
{"name":"FT002","data":{"2017-12-01":1279.0}},
{"name":"FT004","data":{"2017-12-01":3249.0}}
]
newData = {}
data.each do |x|
newData[x[:name]] = [] unless newData[x[:name]].present?
newData[x[:name]].push x[:data]
end
combined = []
newData.each do |index,value|
dateData = {}
value.each do |dateStuff|
dateStuff.each do |dateIndex, dateValue|
dateData[dateIndex] = dateValue
end
end
values = {"name": index, "data": dateData}
combined.push values
end
combined