我有一个哈希数组形式的复杂数据集合。我四处搜索,发现array.map{}
和array.collect
可与.reduce()
或.inject()
方法一起使用,以获得收集总和。但是我只能通过一些非常简单的集合来实现这一点。在我的情况下,我无法获得一些数据。这是一些示例数据块。
=> [{"teacher_name"=>"Imran Ahmad", "categories"=>[{"category_name"=>"Presentation", "weight"=>24}, {"category_name"=>"Speaking", "weight"=>20}, {"category_name"=>"Communication", "weight"=>20}]},
{"teacher_name"=>"t@kpi.com", "categories"=>[{"category_name"=>"Presentation", "weight"=>12}, {"category_name"=>"Speaking", "weight"=>5}, {"category_name"=>"Communication", "weight"=>5}]},
{"teacher_name"=>"t2@kpi.com", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]},
{"teacher_name"=>"tt@kpi.com", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]},
{"teacher_name"=>"asd@kpi.con", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]},
{"teacher_name"=>"Tofiq Ahmad", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]}]
我希望以下列形式总结一下;
"categories"=>[{"category_name"=>"Presentation", "weight"=>224}, {"category_name"=>"Speaking", "weight"=>220}, {"category_name"=>"Communication", "weight"=>320}]
这里每个哈希都是唯一的类别名称。假设类别Presentation
的哈希表示每个哈希中此类别的所有weights
的总和,依此类推。
使用这些方法使用short(“Rails方式”)对此进行排序的任何帮助都将非常感激。
注意:每次都不假设类别名称相同。不期望使用for循环的答案。
答案 0 :(得分:0)
你可以这样试试:
# convert to list of categories hashes
list = array.map {|h| h['categories'] }.flatten
sum_hash = list.inject({}) do |carry, h|
name = h['category_name']
# initiate new Category or get if it's already existed
carry[name] ||= {'category_name' => name, 'weight' => 0}
# increase weight
carry[name]['weight'] += h['weight']
carry
end
你的输出:
{
"Presentation" => {"category_name"=>"Presentation", "weight"=>36},
"Speaking" => {"category_name"=>"Speaking", "weight"=>25},
"Communication" => {"category_name"=>"Communication", "weight"=>25}
}
现在只需将收到的哈希转换为数组:
{ 'categories' => sum_hash.map { |_, v| v } }
答案 1 :(得分:0)
解决方案:
r = a.inject(Hash.new(0)) do |hash, e|
e['categories'].each do |c|
hash[c['category_name']] += c['weight']
end
hash
end
{'categories' => r.map { |k, v| {'category_name' => k, 'weight' => v} }}
结果:
{"categories"=>[
{"category_name"=>"Presentation", "weight"=>36},
{"category_name"=>"Speaking", "weight"=>25},
{"category_name"=>"Communication", "weight"=>25}
]}
答案 2 :(得分:0)
在这里找到我的答案
sum_array = []
teachers_array = [{"teacher_name"=>"Imran Ahmad", "categories"=>[{"category_name"=>"Presentation", "weight"=>24}, {"category_name"=>"Speaking", "weight"=>20}, {"category_name"=>"Communication", "weight"=>20}]},
{"teacher_name"=>"t@kpi.com", "categories"=>[{"category_name"=>"Presentation", "weight"=>12}, {"category_name"=>"Speaking", "weight"=>5}, {"category_name"=>"Communication", "weight"=>5}]},
{"teacher_name"=>"t2@kpi.com", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]},
{"teacher_name"=>"tt@kpi.com", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]},
{"teacher_name"=>"asd@kpi.con", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]},
{"teacher_name"=>"Tofiq Ahmad", "categories"=>[{"category_name"=>"Presentation", "weight"=>0}, {"category_name"=>"Speaking", "weight"=>0}, {"category_name"=>"Communication", "weight"=>0}]}]
teachers_array.each do |teacher|
teacher['categories'].each do |category|
found = sum_array.select{|value| value['category_name'] == category['category_name']}[0]
if found.present? then
sum_array.collect! {|value|
if value['category_name'] == category['category_name'] then
value['weight'] += category['weight']
end
value
}
else
sum_array << {'category_name' => category['category_name'], 'weight' => category['weight']}
end
end
end
<强>输出强>
[{"category_name"=>"Presentation", "weight"=>36}, {"category_name"=>"Speaking", "weight"=>25}, {"category_name"=>"Communication", "weight"=>25}]