web-dev-qa-db-ja.com

Rubyハッシュホワイトリストフィルター

あるフィルターから別のフィルターにキーと値のペアをフィルターで除外する方法を見つけようとしています

たとえば、このハッシュを取得したい

x = { "one" => "one", "two" => "two", "three" => "three"}

y = x.some_function

y == { "one" => "one", "two" => "two"}

ご協力いただきありがとうございます

編集:おそらくこの例では、ホワイトリストフィルターとして動作することを言及する必要があります。つまり、私は私が望んでいないものではなく、私が望むものを知っています。

64
stellard

たぶんこれはあなたが望むものです。

wanted_keys = %w[one two]
x = { "one" => "one", "two" => "two", "three" => "three"}
x.select { |key,_| wanted_keys.include? key }

に含まれる列挙可能なミックスイン。 Array and Hashには、select/reject/each/etc。などの便利なメソッドが多数用意されています。riEnumerableを使用して、ドキュメントを参照することをお勧めします。

54
sris

RailsのActiveSupportライブラリもスライスを提供しますが、キーレベルでハッシュを処理する場合を除きます。

y = x.slice("one", "two") # => { "one" => "one", "two" => "two" }
y = x.except("three")     # => { "one" => "one", "two" => "two" }
x.slice!("one", "two")    # x is now { "one" => "one", "two" => "two" }

これらは非常に素晴らしいものであり、私は常にそれらを使用しています。

102
Brian Guthrie

組み込みのハッシュ関数rejectを使用できます。

x = { "one" => "one", "two" => "two", "three" => "three"}
y = x.reject {|key,value| key == "three" }
y == { "one" => "one", "two" => "two"}

任意のロジックを拒否に入れることができ、ブロックがtrueを返す場合、新しいハッシュのそのキー、値をスキップします。

49
scottd

Railsを使用していて、必要なもののリストがある場合は、スライスからのパラメーターとしてリストを展開できます。

hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
hash.slice(*keys_whitelist)

Railsを使用しない場合、Rubyバージョンでは、以下を実行できます。

hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
Hash[hash.find_all{|k,v| keys_whitelist.include?(k)}] 
8
fotanus

みんなの答えを組み合わせて、この解決策を思いつきました。

 wanted_keys = %w[one two]
 x = { "one" => "one", "two" => "two", "three" => "three"}
 x.reject { |key,_| !wanted_keys.include? key }
 =>{ "one" => "one", "two" => "two"}

助けてくれてありがとう!

編集:

上記は1.8.7以降で動作します

以下は1.9+で動作します:

x.select {| key、_ | wanted_keys.include?キー}

7
stellard
y = x.reject {|k,v| k == "three"}
7
Brian Campbell

フィルタリングにラムダを使用します。これにより、複雑なフィルタリングロジックを記述し、テストを容易にすることができます。フィルタリングロジックが抽出されるという事実により、他のコンテキストでそれを再利用できます。

例:

x = { "one" => "one", "two" => "two", "three" => "three"}

matcher = ->(key,value) { 
  # FILTERING LOGIC HERE 
   !key[/three/]
}

x.select(&matcher) == { "one" => "one", "two" => "two"}
0
metakungfu