Pour ajouter une nouvelle paire à Hash, je fais:
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
Existe-t-il un moyen similaire de supprimer une clé de Hash?
Cela marche:
{:a => 1, :b => 2}.reject! { |k| k == :a } #=> {:b => 2}
mais je m'attendrais à avoir quelque chose comme:
{:a => 1, :b => 2}.delete!(:a) #=> {:b => 2}
Il est important que la valeur de retour soit le hachage restant, donc je pourrais faire des choses comme:
foo(my_hash.reject! { |k| k == my_key })
en une seule ligne.
ruby-on-rails
ruby
ruby-on-rails-3
hashmap
ruby-hash
Misha Moroshko
la source
la source
Réponses:
Rails a un sauf / sauf! méthode qui renvoie le hachage avec ces clés supprimées. Si vous utilisez déjà Rails, il est inutile de créer votre propre version de cela.
la source
require "active_support/core_ext/hash/except"
Oneliner plain ruby, il ne fonctionne qu'avec un rubis> 1.9.x:
La méthode Tap renvoie toujours l'objet sur lequel est invoqué ...
Sinon, si vous en avez besoin
active_support/core_ext/hash
(ce qui est automatiquement requis dans chaque application Rails), vous pouvez utiliser l'une des méthodes suivantes en fonction de vos besoins:sauf qu'il utilise une approche de liste noire, il supprime donc toutes les clés répertoriées comme arguments, tandis que slice utilise une approche de liste blanche, il supprime donc toutes les clés qui ne sont pas répertoriées comme arguments. Il existe également la version bang de ces méthodes (
except!
etslice!
) qui modifient le hachage donné mais leur valeur de retour est différente les deux retournent un hachage. Il représente les clés suppriméesslice!
et les clés conservées pourexcept!
:la source
h
.Hash#except
ne modifiera pas le hachage d'origine.h.dup.tap { |hs| hs.delete(:a) }
pour éviter de modifier le hachage d'origine.Pourquoi ne pas simplement utiliser:
la source
merge
,merge!
,delete
mais pasdetele!
...foo(hash.delete(key) || hash)
delete
ne modifiait pas son paramètre et s'ildelete!
existait et modifiait son paramètre.Il existe de nombreuses façons de supprimer une clé d'un hachage et d'obtenir le hachage restant dans Ruby.
.slice
=> Il renverra les clés sélectionnées et ne les supprimera pas du hachage d'origine. Utilisezslice!
si vous souhaitez supprimer définitivement les clés, sinon utilisez simpleslice
..delete
=> Il supprimera les clés sélectionnées du hachage d'origine (il ne peut accepter qu'une seule clé et pas plus d'une)..except
=> Il renverra les clés restantes mais ne supprimera rien du hachage d'origine. Utilisezexcept!
si vous souhaitez supprimer définitivement les clés, sinon utilisez simpleexcept
..delete_if
=> Dans le cas où vous devez supprimer une clé basée sur une valeur. Cela supprimera évidemment les clés correspondantes du hachage d'origine..compact
=> Il est utilisé pour supprimer toutes lesnil
valeurs du hachage. Utilisezcompact!
si vous souhaitez supprimernil
définitivement les valeurs, sinon utilisez simplecompact
.Résultats basés sur Ruby 2.2.2.
la source
slice
etexcept
sont ajoutés à l'aide deActiveSupport::CoreExtensions::Hash
. Ils ne font pas partie du noyau Ruby. Ils peuvent être utilisés parrequire 'active_support/core_ext/hash'
Hash#slice
est dans la bibliothèque standard. ruby-doc.org/core-2.5.0/Hash.html#method-i-slice Yay!Si vous voulez utiliser du Ruby pur (pas de Rails), ne voulez pas créer de méthodes d'extension (peut-être en avez-vous besoin seulement à un ou deux endroits et ne voulez pas polluer l'espace de noms avec des tonnes de méthodes) et ne voulez pas modifier le hachage en place (c'est-à-dire que vous êtes fan de la programmation fonctionnelle comme moi), vous pouvez «sélectionner»:
la source
J'ai configuré cela de sorte que .remove renvoie une copie du hachage avec les clés supprimées, tout en supprimant! modifie le hachage lui-même. Ceci est conforme aux conventions rubis. par exemple, à partir de la console
la source
Vous pouvez utiliser à
except!
partir de lafacets
gemme:Le hachage d'origine ne change pas.
EDIT: comme le dit Russel, les facettes ont des problèmes cachés et ne sont pas complètement compatibles avec l'API avec ActiveSupport. D'un autre côté, ActiveSupport n'est pas aussi complet que les facettes. À la fin, j'utiliserais AS et laisserais les cas de bord dans votre code.
la source
require 'facets/hash/except'
et ce ne sont pas des "problèmes" (je ne sais pas quels problèmes ils seraient de toute façon autres que 100% AS API). Si vous faites un projet Rails en utilisant AS est logique, sinon Facets a une empreinte beaucoup plus petite.Au lieu de patcher des singes ou d'inclure inutilement de grandes bibliothèques, vous pouvez utiliser des améliorations si vous utilisez Ruby 2 :
Vous pouvez utiliser cette fonctionnalité sans affecter d'autres parties de votre programme, ni avoir à inclure de grandes bibliothèques externes.
la source
en Rubis pur:
la source
Voir Ruby on Rails: Supprimer plusieurs clés de hachage
la source
each
retournerait le tableau.C'était génial si supprimer renvoyait la paire de suppression du hachage. Je fais ça:
la source
Il s'agit d'une méthode en ligne, mais elle n'est pas très lisible. Recommande d'utiliser deux lignes à la place.
la source
Hash#except
etHash#except!
ont déjà été suffisamment mentionnés. LaProc.new
version n'est pas très lisible comme vous le mentionnez et aussi plus compliquée queuse_remaining_hash_for_something(begin hash.delete(:key); hash end)
. Peut-être supprimez-vous simplement cette réponse.Plusieurs façons de supprimer Key in Hash. vous pouvez utiliser n'importe quelle méthode d'en bas
Il y a tellement de façons, vous pouvez consulter le document Ruby de Hash ici .
Je vous remercie
la source
Cela fonctionnerait également:
hash[hey] = nil
la source