ruby-on-rails - Ruby on Rails 人口统计数据

标签 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 = 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
    
  • 代码中的硬编码值

我会通过找到一种计算确切年龄的适当方法来开始重写。 This one似乎没问题:

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)]

然后开始寻找一种合适的方法根据您的 map 对它们进行分组,比如使用 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}

或者,也许,使用 group_by

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]]

等等

关于ruby-on-rails - Ruby on Rails 人口统计数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7442363/

相关文章:

ruby-on-rails - 延迟作业 run_at 未在正确时间运行

ruby-on-rails - 在 Rails activerecord 查询上链接一个额外的订单?

r - 如何计算密度图的概率?

r - 在 R 工作流程中编写函数与逐行解释

python - 解释 scipy.stats.entropy 值

sql - 检查是否有任何数组元素以特定字符 postgres 开头

mySQL "Too many connections"错误受杂种实例数的影响?

php - 哪种语言具有更好的线程功能? PHP 或 ruby

Ruby 语音识别库

ruby - 你如何将 cucumber 场景标记为待处理