J'essaie de comprendre comment filtrer les paires de clés et de valeurs d'un filtre à 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 dans, par exemple, Array and Hash fournit de nombreuses méthodes utiles, telles que sélectionner/rejeter/chaque/etc .. Je vous suggère de consulter la documentation correspondante avec ri Enumerable.
La bibliothèque ActiveSupport de Rails vous donne également des tranches et à l'exception du traitement du 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 assez Nice, et je les utilise tout le temps.
Vous pouvez simplement utiliser la fonction de rejet intégrée de Hash.
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 true, il ignorera cette clé, valeur dans le nouveau hachage.
Pour améliorer un peu la réponse @scottd, si vous utilisez Rails et avez une liste de ce dont vous avez besoin, vous pouvez développer la liste en tant que paramètres de la tranche. Par exemple
hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
hash.slice(*keys_whitelist)
Et sans Rails, quelle que soit la version de Ruby, vous pouvez effectuer les opérations suivantes:
hash = { "one" => "one", "two" => "two", "three" => "three"}
keys_whitelist = %W(one two)
Hash[hash.find_all{|k,v| keys_whitelist.include?(k)}]
y = x.reject {|k,v| k == "three"}
En combinant les réponses de chacun, je propose 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:
Ce qui précède fonctionne en 1.8.7+
Ce qui suit fonctionne dans 1.9+:
x.select {| key, _ | wanted_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 la 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"}