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