Ruby on rails RubyonRails人口统计数据
我为PS3游戏制作了一个网站,我有很多用户。我想让比赛的基础上人民的位置,也希望以年龄组。当用户以YYYY-MM-DD格式注册输入时,我将数据拉入哈希,如下所示:Ruby on rails RubyonRails人口统计数据,ruby-on-rails,ruby,statistics,Ruby On Rails,Ruby,Statistics,我为PS3游戏制作了一个网站,我有很多用户。我想让比赛的基础上人民的位置,也希望以年龄组。当用户以YYYY-MM-DD格式注册输入时,我将数据拉入哈希,如下所示: # Site.rb has_many :members def ages ages = {"Under 18" => 0, "19-24" => 0, "25-35" => 0, "36-50" => 0, "51-69" => 0,"70+" => 0} ages_results =
# Site.rb
has_many :members
def ages
ages = {"Under 18" => 0, "19-24" => 0, "25-35" => 0, "36-50" => 0, "51-69" => 0,"70+" => 0}
ages_results = self.members.count("DATE_FORMAT(dob, '%Y')", :group =>"DATE_FORMAT(dob, '%Y')")
ages_results.each do |k,v|
k = k.to_i
if k.between?(18.years.ago.strftime("%Y").to_i, 0.years.ago.strftime("%Y").to_i)
ages["Under 18"] += v
elsif k.between?(24.years.ago.strftime("%Y").to_i, 19.years.ago.strftime("%Y").to_i)
ages["19-24"] += v
elsif k.between?(35.years.ago.strftime("%Y").to_i, 25.years.ago.strftime("%Y").to_i)
ages["25-35"] += v
elsif k.between?(50.years.ago.strftime("%Y").to_i, 36.years.ago.strftime("%Y").to_i)
ages["36-50"] += v
elsif k.between?(69.years.ago.strftime("%Y").to_i, 51.years.ago.strftime("%Y").to_i)
ages["51-69"] += v
elsif k > 70.years.ago.strftime("%Y").to_i
ages["70+"] += v
end
end
ages
end
我不是一个专业的ruby开发人员,也不确定上面的方法是好的还是可以做得更好,有人能给我一些建议吗
干杯代码中需要注意的几点:
- 您似乎忽略了用户出生的月份和日期
- 不必要地在字符串之间进行转换:
可以写成50.years.ago.strftime("%Y").to_i
50.years.ago.year
- 代码中的所有硬编码值
require 'date'
def age(dob)
now = Time.now.utc.to_date
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
然后,我会将年龄表提取到一个单独的结构中,以便能够在需要时轻松地对其进行更改,并将其可视化地放在一起:
INF = 1/0.0 # convenient infinity
age_groups = {
(0..18) => 'Under 18',
(19..24) => '19-24',
(25..35) => '25-35',
(36..50) => '36-50',
(51..69) => '51-69',
(70..INF) => '70+'
}
接下来,您可以将用户的出生日期数组作为输入:
users_dobs = [Date.new(1978,4,16), Date.new(2001,6,13), Date.new(1980,10,22)]
并开始根据地图找到合适的方法对它们进行分组,比如使用inject
:
p users_dobs.each_with_object({}) {|dob, result|
age_group = age_groups.keys.find{|ag| ag === age(dob)}
result[age_group] ||= 0
result[age_group] += 1
}
#=>{25..35=>2, 0..18=>1}
或者,也许可以使用groupby
p users_dobs.group_by{|dob|
age_groups.keys.find{|ag| ag === age(dob)}
}.map{|k,v| [age_groups[k], v.count]}
#=>[["25-35", 2], ["Under 18", 1]]
等等。感谢您为答案付出的努力,它帮助我的代码变得更加优雅!