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

Ruby数学运算符可以存储在散列中并在以后动态应用吗?,ruby,operators,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.eac

有没有办法用
%
+
等值设置哈希? 我想创建一个方法,该方法接受一个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

当然,将它们存储为字符串(或符号)并使用
object.send(函数名、参数)

>运算符=[“”、“%”、“+”]
=> ["", "%", "+"] 
>运算符。每个{op}put[“10{op}3:,10.send(op,3)].join}
10<3:false
10>3:正确
10 % 3: 1
10 + 3: 13

在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

这应该像预期的那样工作:

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
def range_过滤器(数组,args)
检查程序={:min=>::>}
checker.each|key{| key | array.delete|u if{| x | x.send checker[key],args[key]}
array.each{| num | put num}
结束

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

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

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

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

=
是一种特殊的语法情况。它实际上执行
==
方法,然后翻转生成的布尔值。所以你不能运行
=作为一种方法。您必须执行
!1.发送(:=,2)
。如果你想支持这一点,你可能必须检测到这个符号和特殊情况。遗憾的是,我仍然使用1.8.7。但我很高兴听到他们修复了这种不一致性:)在Ruby 1.9中,
也是一种方法,因此它更像是
1.send(:=,2.send(:!)
。的可能副本
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
checkers = 
  [ lambda{ |x| x > 10 },
    lambda{ |x| x < 30 } ]

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

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