Ruby, value bucketing, beautify code

前端 未结 5 639
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-25 02:04

So I have this code:

def self.age_to_bucket(age)
  age = age.to_i

  if age >= 0 && age <= 12
    1
  elsif age >= 13 && age <= 17
          


        
相关标签:
5条回答
  • 2021-01-25 02:21

    You can rewrite if age.in? (0..12) to (0..12).include? age, which is vanilla Ruby.

    0 讨论(0)
  • 2021-01-25 02:26
    irb(main):010:0> a = {1 => 0..12, 2 => 13..17} # insert other values here
    => {1=>0..12, 2=>13..17}
    irb(main):011:0> age = 16
    => 16
    irb(main):012:0> a.keys.find {|k| a[k].include?(age) }
    => 2
    
    0 讨论(0)
  • 2021-01-25 02:31
    def self.age_to_bucket age
      case age=age.to_i
        when  0..12 then 1
        when 13..17 then 2
        when 18..24 then 3
        when 25..29 then 4
        when 30..34 then 5
        when 35..39 then 6
        when 40..49 then 7
        when 50..64 then 8
        else age >= 65 ? 9 : 0
      end
    end
    
    0 讨论(0)
  • 2021-01-25 02:32

    One way is to use case

    result = case age
     when 0..12 then 1
     when 13..17 then 2
     when 18..24 then 3
     when 25..29 then 4
     -------- so on
     else 0
    end
    

    Another way would be to eliminate the redundant && in the condition.

    if age < 0 
      0
    elsif age < 13
      1
    elsif age < 18
      2
    elsif age < 25
      3
    elsif age < 30
      4
    elsif age < 35
      5
    elsif age < 40
      6
    elsif age < 50
      7
    elsif age < 65
      8
    else
      9
    
    0 讨论(0)
  • 2021-01-25 02:43

    Just for fun (this is not the efficient way, but for small arrays is just fine):

    ranges = [0, 13, 18, 25, 30, 35, 40, 50, 65, Float::INFINITY].each_cons(2).map { |a, b| (a..b) }
    n = ranges.map.with_index { |range, idx| idx if range.include?(15) }.compact.first + 1 
    #=> 2
    

    Note that if the intervals were dynamic you'd have to implement it in a similar fashion.

    0 讨论(0)
提交回复
热议问题