我对每个项目都有一个标记数组,如下所示:
item1 = ['new', 'expensive']
item2 = ['expensive', 'lame']
我还有一个基于可能标签的字符串形式的布尔表达式:
buy_it = "(new || expensive) && !lame"
如何根据与商品相关联的标签来确定商品是否符合购买标准?我最初的想法是对buy_it中的所有单词执行gsub,使其基于存在于itemx标记数组中的“true”或“false”,然后执行结果字符串以获得布尔结果。
但是既然Ruby社区通常比我更有创造力,有没有更好的解决方案呢?
编辑:
为了澄清,我的例子中的buy_it是动态的,用户可以在运行时更改购买条件。
发布于 2010-04-08 21:52:51
按照您的查询思路,不是每次都用真/假替换每个单词,为什么不把每个“gsub
”替换成一个可以重用的表达式,例如示例buy_it
buy_it = "(new || expensive) && !lame"
buy_it_expr = buy_it.gsub(/(\w+)/, 'tags.include?("\1")')
puts buy_it_expr
=> (tags.include?("new") || tags.include?("expensive")) && !tags.include?("lame")
可以将其计算为Proc
并按如下方式使用:
buy_it_proc = eval "Proc.new { |tags| #{buy_it_expr} }"
buy_it_proc.call(item1)
=> true
buy_it_proc.call(item2)
=> false
当然,必须注意表达式不包含恶意代码。(一种解决方案可能是从字符串中剥离除允许的运算符字符之外的所有字符,当然,在eval过程中要小心异常。)
发布于 2010-04-08 21:41:40
哈希在这里是一个很好的候选者。
items = {'ipad' => ['new', 'expensive'], 'kindle' => ['expensive', 'lame']}
items.each do |name,tags|
if tags.include?('new' || 'expensive') && !tags.include?('lame')
puts "buy #{name}."
else
puts "#{name} isn't worth it."
end
end
https://stackoverflow.com/questions/2603528
复制相似问题