Filtre Whitelist de Ruby Hash

J’essaie de comprendre comment je peux filtrer les paires de clés et de valeurs d’un filtre dans un autre

Par exemple, je veux prendre ce hash

x = { "one" => "one", "two" => "two", "three" => "three"} y = x.some_function y == { "one" => "one", "two" => "two"} 

Merci de votre aide

EDIT: devrait probablement mentionner que dans cet exemple, je veux qu’il se comporte comme un filtre de liste blanche. C’est-à-dire que je sais ce que je veux, pas ce que je ne veux pas.

Peut-être que c’est ce que vous voulez.

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

Le mixin Enumerable qui est inclus par exemple dans Array et Hash fournit beaucoup de méthodes utiles comme select / reject / each / etc. Je vous suggère de regarder la documentation avec ri Enumerable.

La bibliothèque ActiveSupport de Rails vous donne également des tranches et excepté pour gérer le hachage au niveau clé:

 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" } 

Ce sont plutôt sympas et je les utilise tout le temps.

Vous pouvez simplement utiliser le rejet de fonction de hachage intégré.

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

Vous pouvez mettre la logique de votre choix dans le rejet, et si le bloc renvoie la valeur true, cette clé sera ignorée et sera ajoutée au nouveau hachage.

 y = x.reject {|k,v| k == "three"} 

Améliorer un peu la réponse @scottd, si vous utilisez des rails et avez une liste de ce dont vous avez besoin, vous pouvez développer la liste en tant que parameters à partir de la tranche. Par exemple

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

Et sans rails, pour toute version de Ruby, vous pouvez faire ce qui suit:

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

En combinant les réponses de chacun, j’ai trouvé cette solution:

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

Merci pour votre aide les gars!

MODIFIER:

Le travail ci-dessus dans 1.8.7+

Les travaux suivants en 1.9+:

x.select {| key, _ | want_keys.include? clé}

J’utiliserais un lambda pour filtrer. Cela vous permettra à la fois d’écrire une logique de filtrage complexe et de la tester facilement. Le fait que la logique de filtrage soit extraite permettra de le réutiliser dans d’autres contextes.

ex:

 x = { "one" => "one", "two" => "two", "three" => "three"} matcher = ->(key,value) { # FILTERING LOGIC HERE !key[/three/] } x.select(&matcher) == { "one" => "one", "two" => "two"}