[英]Ruby: Is there a more efficient way to convert a subset of hash keys to underscored symbols?
[英]Most efficient way to convert a ruby hash with array as keys to one with single values as keys
我坚持重新安排红宝石哈希的最佳方法是什么。
主要目标是按月和计数对mysql的结果进行分组。
为此,我提出了以下要求:
@data = Model.find(params[:id])
.jobs
.group('year(created_at)')
.group('month(created_at)')
.count(:id)
这给了我:
#=> {[2013, 12]=>9, [2014, 1]=>4, [2014, 3]=>3,
# [2014, 4]=>1, [2014, 6]=>1, [2014, 7]=>1, [2014, 10]=>2}
我正在尝试使用更整洁的哈希或数组来转换为JSON,其中年份不重复。
我该如何使用类似{"Year" => [Month,Count value]}
? (或其他形式)
理念? (我运行ruby 2.2)
@mudosobwa提出的答案可能是正确的,但是由于目标是json文件,因此您可能需要一些“命名”键。 我建议你这个:
formated_results = @data.group_by{|k, v| k[0]}.collect{|k,v| {year: k, datas: v.collect{|vv| {month: vv.first.last, count: vv.last}}}}
# {:year=>2013, :datas=>[{:month=>12, :count=>9}]}
# {:year=>2014, :datas=>[{:month=>1, :count=>4}, {:month=>3, :count=>3}, {:month=>4, :count=>1}, {:month=>6, :count=>1}, {:month=>7, :count=>1}, {:month=>10, :count=>2}]}
编辑 :没有group_by方法的另一个解决方案:
formated_results = Hash.new{|h,k| h[k] = []}
@data.each{|k,v| formated_results[k[0]] << {month: k[1], count: v}}
formated_results = formated_results.collect{|k, v| {year: k, datas: v}}
# {:year=>2013, :datas=>[{:month=>12, :count=>9}]}
# {:year=>2014, :datas=>[{:month=>1, :count=>4}, {:month=>3, :count=>3}, {:month=>4, :count=>1}, {:month=>6, :count=>1}, {:month=>7, :count=>1}, {:month=>10, :count=>2}]}
那你只需要
formated_results.to_json
json结果应为:
[
{
"year": 2013,
"datas": [
{ "month": 12, "count": 9 }
]
},
{
"year": 2014,
"datas": [
{ "month": 1, "count": 4 },
{ "month": 3, "count": 3 },
{ "month": 4, "count": 1 },
{ "month": 6, "count": 1 },
{ "month": 7, "count": 1 },
{ "month": 10, "count": 2 }
]
}
]
假设您已经在@data
哈希,则可以:
@data.inject({}) do |memo, ((y, m), cnt)|
(memo[y] ||= {})[m] = cnt
memo
end
#⇒ {
# 2013 => {12 => 9},
# 2014 => {1 => 4, 10 => 2, 3 => 3, 4 => 1, 6 => 1, 7 => 1}
# }
正如@Surya在评论中指出的那样,它应该是哈希Year => Hash[Month, Count]
。 当您仍然希望拥有Month, Count
数组时Month, Count
:
@data.inject({}) do |memo, ((y, m), cnt)|
memo[y] ||= []
memo[y] << [m, cnt]
memo
end
到json:
require 'json'
result.to_json
#=> "{\"2013\":{\"12\":9},\"2014\":{\"1\":4,\"3\":3,\"4\":1,\"6\":1,\"7\":1,\"10\":2}}"
@data.to_a.group_by{|ym, c| ym.first }.map{|year, months| [year,months.map{|m,cnt| [m.last, cnt] }] }.to_h
=> {2013=>[[12, 9]], 2014=>[[1, 4], [3, 3], [4, 1], [6, 1], [7, 1], [10, 2]]}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.