2011-12-08 7 views
4

<,>,%,+などの値を持つハッシュを設定する方法はありますか? intの配列とパラメータを持つハッシュを受け入れるメソッドを作成したいと思います。Ruby数学演算子をハッシュに格納し、後で動的に適用できるか?

以下の方法では、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 
+0

可能な重複(それはあまりにも動作しますが、あなたはlambda{ |x| x % 3 == 1 }を望んでいる場合?)との比較Ruby?](http://stackoverflow.com/questions/13060239/can-i-dynamically-call-a-math-operator-in-ruby) –

答えて

5

を使用し、さらに数学は、メソッド呼び出しです。数学記号はルビ記号として保存することができます。これらの行が同一である:それと

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 
+0

これは次の場所でも動作しますか? – Btuman

+0

'!='は特別な構文の場合です。実際には '=='メソッドを実行し、結果のブール値を反転します。したがって、 '!='をメソッドとして直接悲しいように実行することはできません。あなたは '!1.end(:==、2)'をしなければなりません。そのシンボルを検出しなければならない場合があります。 –

+0

私は私のirbでそれを試してみて、それは私のために働く。 Ruby 1.9.2 – iain

4

確認する文字列(または記号)としてそれらを保存し、Rubyで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 
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 Sを使用しますプレーンオペレータの演算子は数値オブジェクトの特別なメソッドなので、sendとそれに相当するSymbolを動的に呼び出すことができます。

0

この場合、シンボルを使用しても読みやすくすることはできません。これを試してみてください:

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] 
関連する問題