2011-12-16 39 views
1

所以我有這樣的代碼:紅寶石,價值鏟裝,美化代碼

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

    if age >= 0 && age <= 12 
    1 
    elsif age >= 13 && age <= 17 
    2 
    elsif age >= 18 && age <= 24 
    3 
    elsif age >= 25 && age <= 29 
    4 
    elsif age >= 30 && age <= 34 
    5 
    elsif age >= 35 && age <= 39 
    6 
    elsif age >= 40 && age <= 49 
    7 
    elsif age >= 50 && age <= 64 
    8 
    elsif age >= 65 
    9 
    else 
    0 
    end 
end 

如何提高不失其可讀性這個代碼?

我知道我可以使用#in?與範圍,就像這樣:

if age.in? (0..12) 

#in?是的ActiveSupport,我寧願用更獨立的方式。

+0

你喜歡這個還是太抽象了? `[0,12,13,17,...]。find_interval(15)#=> 2`。實現起來相當簡單(有效地做起來有點困難)。 – tokland 2011-12-16 08:59:51

+0

我的意思是:`[0,13,18,...]。find_interval(15)` – tokland 2011-12-16 09:05:53

+0

我寧願不自己實現任何東西,因爲我只需要在一個地方使用此代碼。 – 2011-12-16 09:08:29

回答

6

的一種方法是用例

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 

另一種方式是,消除在條件冗餘& &。

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 

UPD:代碼的最終版本,因爲這主題中的所有意見的結果:https://gist.github.com/1485288

+0

在'case'情況下,你會如何表達`age> 65`? – 2011-12-16 09:06:29

1

可以重寫if age.in? (0..12)(0..12).include? age,這是vanilla Ruby

0
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 
2
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 
1

只是爲了好玩(這不是有效的方法,但對於小陣就好了):

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 

注意,如果間隔是動態的,你不得不實施它以類似的方式。