Ruby数学运算符可以存储在哈希中并稍后动态应用吗?

时间:2011-12-08 20:47:24

标签: ruby operators

有没有办法设置包含<>%+等值的哈希值? 我想创建一个接受int数组的方法,以及一个带参数的哈希。

在下面的方法中,array是要过滤的数组,hash是参数。我们的想法是删除任何小于min或大于max的数字。

def range_filter(array, hash) 
  checker={min=> <, ,max => >} # this is NOT  working code, this the line I am curious about
  checker.each_key {|key| array.delete_if {|x| x checker[key] args[key] }
  array.each{|num| puts num}
end

期望的结果将是

array=[1, 25, 15, 7, 50]
filter={min=> 10, max=> 30} 
range_filter(array, filter)
# => 25
# => 15

4 个答案:

答案 0 :(得分:5)

在ruby中,即使数学也是方法调用。并且数学符号可以存储为ruby符号。这些行是相同的:

1 + 2         # 3
1.+(2)        # 3
1.send(:+, 2) # 3

因此,将它存储起来很简单:

op = { :method => :> }
puts 1.send(op[:method], 2) # false
puts 3.send(op[:method], 2) # true

答案 1 :(得分:4)

当然,将它们存储为字符串(或符号)并使用object.send(function_name, argument)

> operators = ["<", ">", "%", "+"]
=> ["<", ">", "%", "+"] 
> operators.each{|op| puts ["   10 #{op} 3: ", 10.send(op,3)].join}
   10 < 3: false
   10 > 3: true
   10 % 3: 1
   10 + 3: 13

答案 2 :(得分:1)

这应该像预期的那样起作用:

def range_filter(array, args)
  checker = { :min=> :<, :max => :> }
  checker.each_key { |key| array.delete_if {|x| x.send checker[key], args[key] } }
  array.each { |num| puts num }
end

只需使用Symbol代替普通运算符即可。运算符是数字对象的特殊方法,因此您只需使用send及其Symbol等效项即可动态调用它们。

答案 3 :(得分:0)

使用符号猜测在这种情况下不会增加可读性。试试这个:

checkers = 
  [ lambda{ |x| x > 10 },
    lambda{ |x| x < 30 } ]

[1, 25, 15, 7, 50].select{ |x| checkers.all?{ |c| c[x] } } 
#=> [25, 15]

<强>更新

比较(它也有效,但如果你想要lambda{ |x| x % 3 == 1 }怎么办?)

checkers = 
  { :> => 10,
    :< => 30 }

[1, 25, 15, 7, 50].select{ |x| checkers.all?{ |k, v| x.send(k, v) } } 
#=> [25, 15]