2011-03-05 31 views
1

在ruby/rails3中,我需要做一些沉重的文本解析才能找到某个字符串。现在我在做类似如下:Rails - IF复杂语句阻塞,如何优化W/O降低可读性?

extract_type1 = body.scan(/(stuff)/m).size 
extract_type2 = body.scan(/(stuff)/m).size 
extract_type3 = body.scan(/(stuff)/m).size 
extract_type4 = body.scan(/(stuff)/m).size 
extract_type5 = body.scan(/(stuff)/m).size 

if extract_type1 > 0 
elsif extract_type2 > 0 
elsif extract_type3 > 0 
elsif extract_type4 > 0 
elsif extract_type5 > 0 

这里的问题是,我需要不断基础上添加应用程序提取的类型。当情况发生extract_type1> 0而其余不需要时,这会导致很多处理。

但是与此同时,将提取逻辑从if块中分离出来会很好,很干净,因为那样会很麻烦,很难阅读。

有关如何在不影响可读性的情况下对其进行优化的想法?

感谢

回答

2

怎么样储存您所有的“关键词”你在阵列中搜索和遍历它想:

stuff = ["stuff1", "stuff2"] 

stuff.each do |c_stuff| 
    if body.scan(/(#{Regexp.escape(c_stuff)})/m).size > 0 
    # do something 
    # break the loop 
    break 
    end 
end  

编辑:如果你需要的元素的索引,你可以使用each_with_index do |c_stuff, c_index|

+0

谢谢,但我不认为这会工作?因为如果你匹配第一个正则表达式,你仍然只是运行每一个正则表达式,为什么要运行其他所有的正则表达式呢? – AnApprentice 2011-03-05 00:27:22

+0

而不是'each'使用'first',并确保你的'if'语句返回一个真值。一旦找到第一个命中,这将停止循环。 @sled可能会更新他的答案。 – Phrogz 2011-03-05 02:04:14

+0

如果进入循环,则可以使用'break'语句打破循环。即在'#做某事'给'break'之后。 – rubyprince 2011-03-05 12:43:21

0

懒惰的评估可能适合你;只是转换你的extract_X变量lambda表达式,这样的数值计算上使用:

extract_type1 = lambda { body.scan(/(stuff)/m).size } 
extract_type2 = lambda { body.scan(/(stuff)/m).size } 
extract_type3 = lambda { body.scan(/(stuff)/m).size } 
extract_type4 = lambda { body.scan(/(stuff)/m).size } 
extract_type5 = lambda { body.scan(/(stuff)/m).size } 

if extract_type1.call > 0 
elsif extract_type2.call > 0 
elsif extract_type3.call > 0 
elsif extract_type4.call > 0 
elsif extract_type5.call > 0 

如果您使用的extract_X值超过一次,那么你可以添加记忆化的lambda表达式,这样的数值计算上第一访问,然后缓存,以便后续访问只使用已经计算的值。