如何重构重复5次的if语句,简化网球比赛胜负判断的代码逻辑
解决方案
方案1:不修改现有数据库结构的重构写法
你之前的写法问题在于直接拼接的字符串是属性名,不是对应属性的实际值。在Ruby/Rails环境下,可以通过send方法动态调用属性的getter方法拿到实际值,重构后代码如下:
def find_winner team_a_win_count = 0 team_b_win_count = 0 1.upto(5) do |n| a_score = send("team_a_set_#{n}") b_score = send("team_b_set_#{n}") # 任意一方比分不存在就跳过当前局判断 next unless a_score.present? && b_score.present? if a_score > b_score team_a_win_count += 1 elsif b_score > a_score team_b_win_count += 1 end end if team_a_win_count > team_b_win_count 'Team A won' elsif team_b_win_count > team_a_win_count 'Team B won' else 'Draw' end end
如果是ActiveRecord模型场景,也可以用read_attribute("team_a_set_#{n}")替代send,效果一致。
方案2:基于哈希存储的最优写法
你后续调整为哈希存储比分的方案是更合理的架构,不仅避免了大量冗余字段,后续调整赛制也不需要修改表结构。假设存储比分的哈希字段为set_scores,参考结构和逻辑如下:
# set_scores 哈希存储示例(数据库可使用json/jsonb类型存储) # { # 1 => { a: 6, b: 4 }, # 2 => { a: 3, b: 6 }, # 3 => { a: 7, b: 5 } # } def find_winner a_win_count, b_win_count = 0, 0 set_scores.each do |_, score| next unless score[:a].present? && score[:b].present? a_win_count += 1 if score[:a] > score[:b] b_win_count += 1 if score[:b] > score[:a] end case a_win_count <=> b_win_count when 1 then 'Team A won' when -1 then 'Team B won' else 'Draw' end end
内容的提问来源于stack exchange,提问作者r3b00t
相关产品推荐
相关产品推荐

