【发布时间】:2016-09-23 03:35:06
【问题描述】:
我想知道如何通过递归对这个哈希数组中的“分析”值求和。
输入:
[{"id"=>"1234",
"id_data"=>
[{"segment"=>{"segment_name"=>"Android"},
"metrics"=>
{
"logins"=>[1000, 2000],
"sign_ups_conversion"=>{
"count"=>[500, 200],
"cost"=>[2, 4]
}
},
},
{"segment"=>{"segment_name"=>"iOS"},
"metrics"=>
{
"logins"=>[5000, 10000],
"sign_ups_conversion"=>{
"count"=>[100, 50],
"cost"=>[6, 8]
}
},
}
]
},
{"id"=>"5678",
"id_data"=>
[{"segment"=>{"segment_name"=>"Android"},
"metrics"=>
{
"logins"=>[3000, 2000],
"sign_ups_conversion"=>{
"count"=>[300, 400],
"cost"=>[2, 4]
}
},
},
{"segment"=>{"segment_name"=>"iOS"},
"metrics"=>
{
"logins"=>[5000, 10000],
"sign_ups_conversion"=>{
"count"=>[100, 50],
"cost"=>[6, 8]
}
},
}
]
}]
输出:
{
"Android"=>{
"ids" => ['1234','5678'],
"segment" => {"segment_name"=>"Android"},
"id_data" => [{
"logins" => [4000, 4000], # sum by index from 'Android' logins ("logins"=>[1000, 2000] & "logins"=>[3000, 2000]),
"sign_ups_conversion" => {
"count" => [800, 600], # sum by index from 'Android' sign ups count ("count"=>[500, 200] & "count"=>[300, 400])
"cost" => [4, 8] # sum by index from 'Android' sign ups cost ("cost"=>[2, 4] & "cost"=>[2, 4])
}
}]
},
"iOS"=>{
"ids" => ['1234','5678'],
"segment" => {"segment_name"=>"iOS"},
"id_data" => [{
"logins" => [10000, 20000], # sum by index from 'iOS' logins ("logins"=>[5000, 10000] & "logins"=>[5000, 10000]),
"sign_ups_conversion" => {
"count" => [200, 100], # sum by index from 'iOS' sign ups count ("count"=>[100, 50] & "count"=>[100, 50])
"cost" => [12, 16] # sum by index from 'iOS' sign ups cost ("cost"=>[6, 8] & "cost"=>[6, 8])
}
}]
}
}
我,试图用这种方法解决它,但它没有计算使用哈希格式 (sign_ups_conversion) 的分析,并且仍在弄清楚结果应该如何等于输出。
def aggregate_by_segments(stats_array)
results = {}
stats_array.each do |stats|
stats['id_data'].each do |data|
segment_name = data['segment']['segment_name']
results[segment_name] ||= {}
(results[segment_name]['ids'] ||= []) << stats['id']
results[segment_name]['segment'] ||= data['segment']
results[segment_name]['id_data'] ||= [{}]
data['metrics'].each do |metric, values|
next if skip_metric?(values)
(results[segment_name]['id_data'][0][metric] ||= []) << values
end
end
end
sum_segments(results)
end
def sum_segments(segments)
segments.each do |segment, segment_details|
segment_details['id_data'][0].each do |metric, values|
segment_details['id_data'][0][metric] = sum_segment_metric(values)
end
end
segments
end
def sum_segment_metric(metric_value)
metric_value.transpose.map { |x| x.reduce(:+) }
end
# I skipped hash format for now
def skip_metric?(metric_values)
!metric_values.is_a? Array
end
############################################
# calls it with aggregate_by_segments(input)
############################################
我认为我们应该使用递归,但我还在想办法,有人可以帮助我吗?
提前致谢!
【问题讨论】:
-
这是一组相当复杂的代码,需要很多人才能为您提供解决方案。无论如何,解决一个大问题的方法是把它分解成几个小问题。为什么不这样做?通过将其分解成更易于理解的部分,您可以提出范围更窄的特定问题,这些问题更有可能得到及时的回答。哪些部分确实起作用(如果有)?哪些部分没有?那么,第一个里程碑是什么? (顺便说一句,我认为您不需要递归。)
-
除了非常大之外,您的示例数据是非常特定的。考虑发布更通用(更小)的结构。
-
另一件可能有帮助的事情是你可以用简单的英语写下需要发生的事情。此外,永远不要低估橡皮鸭的力量。 ;) (en.wikipedia.org/wiki/Rubber_duck_debugging)
-
而且,对于按段分组,您可以使用类似
result = input.each_with_object({}) do |id_hash, res| id = id_hash['id'] id_hash['id_data'].each do |id_data| segment = id_data['segment']['segment_name'] res[segment] ||= [] res[segment] << id_data.merge('id' => id) end end puts result -
@KeithBennett 对不起,那是在午夜。是的,你是对的,问题是广泛的
标签: arrays ruby recursion hash