Can Ruby math operators be stored in a hash and be applied dynamically later?

Is it possible to set a hash with values ​​like < , > , % , + , etc.? I want to create a method that takes an array of ints and a hash with parameters.

In the method below, array is the filtered array, and hash is the parameters. The idea is that any number is less than min or more than 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 

Desired Results:

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

In ruby, even math is a method challenge. And math symbols can be stored as ruby ​​symbols. These lines are identical:

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

Thus, armed with this, keeping it simple:

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

be sure to save them as strings (or characters) and use 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 
+4
source

This should work as expected:

 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 

Just use Symbol instead of simple operators. Operators are special methods for numeric objects, so you can simply use send and their Symbol equivalent to dynamically call them.

+1
source

Guess that using characters in this case does not increase readability. Try the following:

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

Update

Compare with (it works too, but what if you wanted 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] 
0
source

Source: https://habr.com/ru/post/1385421/


All Articles