Um Hash ein neues Paar hinzuzufügen, gehe ich wie folgt vor:
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
Gibt es eine ähnliche Möglichkeit, einen Schlüssel aus Hash zu löschen?
Das funktioniert:
{:a => 1, :b => 2}.reject! { |k| k == :a } #=> {:b => 2}
aber ich würde erwarten, etwas zu haben wie:
{:a => 1, :b => 2}.delete!(:a) #=> {:b => 2}
Es ist wichtig, dass der Rückgabewert der verbleibende Hash ist, damit ich Dinge tun kann wie:
foo(my_hash.reject! { |k| k == my_key })
in einer Zeile.
ruby-on-rails
ruby
ruby-on-rails-3
hashmap
ruby-hash
Mischa Moroshko
quelle
quelle
Antworten:
Schienen hat eine Ausnahme / Ausnahme! Methode , die den Hash mit diesen entfernten Schlüsseln zurückgibt. Wenn Sie bereits Rails verwenden, macht es keinen Sinn, eine eigene Version davon zu erstellen.
quelle
require "active_support/core_ext/hash/except"
Oneliner normaler Rubin, funktioniert nur mit Rubin> 1.9.x:
Tap- Methode gibt immer das Objekt zurück, für das aufgerufen wird ...
Andernfalls können Sie bei Bedarf
active_support/core_ext/hash
(was in jeder Rails-Anwendung automatisch erforderlich ist) je nach Ihren Anforderungen eine der folgenden Methoden verwenden:Ausgenommen wird ein Blacklist-Ansatz verwendet, sodass alle als Argumente aufgelisteten Schlüssel entfernt werden , während Slice einen Whitelist-Ansatz verwendet, sodass alle Schlüssel entfernt werden, die nicht als Argumente aufgeführt sind. Es gibt auch die Bang-Version dieser Methoden (
except!
undslice!
), die den angegebenen Hash ändern, aber ihr Rückgabewert ist unterschiedlich. Beide geben einen Hash zurück. Es stellt die entfernten Schlüssel fürslice!
und die Schlüssel dar, die für Folgendes aufbewahrt werdenexcept!
:quelle
h
.Hash#except
ändert den ursprünglichen Hash nicht.h.dup.tap { |hs| hs.delete(:a) }
diese Option , um zu vermeiden, dass der ursprüngliche Hash geändert wird.Warum nicht einfach verwenden:
quelle
merge
,merge!
,delete
, aber nichtdetele!
...foo(hash.delete(key) || hash)
delete
es seinen Parameter nicht ändern würde und wenn esdelete!
existiert und seinen Parameter ändern würde.Es gibt viele Möglichkeiten, einen Schlüssel aus einem Hash zu entfernen und den verbleibenden Hash in Ruby abzurufen.
.slice
=> Es werden ausgewählte Schlüssel zurückgegeben und nicht aus dem ursprünglichen Hash gelöscht. Verwendenslice!
Sie diese Option, wenn Sie die Schlüssel dauerhaft entfernen möchten. Andernfalls verwenden Sie einfachslice
..delete
=> Es löscht die ausgewählten Schlüssel aus dem ursprünglichen Hash (es kann nur einen Schlüssel und nicht mehr als einen akzeptieren)..except
=> Es werden die verbleibenden Schlüssel zurückgegeben, aber nichts aus dem ursprünglichen Hash gelöscht. Verwendenexcept!
Sie diese Option, wenn Sie die Schlüssel dauerhaft entfernen möchten. Andernfalls verwenden Sie einfachexcept
..delete_if
=> Falls Sie einen Schlüssel basierend auf einem Wert entfernen müssen. Es werden offensichtlich die passenden Schlüssel aus dem ursprünglichen Hash entfernt..compact
=> Es wird verwendet, um allenil
Werte aus dem Hash zu entfernen . Verwendencompact!
Sie diese Option, wenn Sie dienil
Werte dauerhaft entfernen möchten. Andernfalls verwenden Sie einfachcompact
.Ergebnisse basierend auf Ruby 2.2.2.
quelle
slice
undexcept
werden mit hinzugefügtActiveSupport::CoreExtensions::Hash
. Sie sind nicht Teil des Ruby-Kerns. Sie können vonrequire 'active_support/core_ext/hash'
Hash#slice
in der Standardbibliothek ist. ruby-doc.org/core-2.5.0/Hash.html#method-i-slice Yay!Wenn Sie reines Ruby (keine Rails) verwenden möchten, möchten Sie keine Erweiterungsmethoden erstellen (möglicherweise benötigen Sie diese nur an ein oder zwei Stellen und möchten den Namespace nicht mit Tonnen von Methoden verschmutzen) und möchten dies nicht Wenn Sie den Hash an Ort und Stelle bearbeiten (dh Sie sind ein Fan von funktionaler Programmierung wie ich), können Sie Folgendes auswählen:
quelle
Ich habe dies so eingerichtet, dass .remove eine Kopie des Hashs mit entfernten Schlüsseln zurückgibt, während remove! Ändert den Hash selbst. Dies steht im Einklang mit Rubinkonventionen. zB von der Konsole
quelle
Sie können
except!
aus demfacets
Edelstein verwenden:Der ursprüngliche Hash ändert sich nicht.
BEARBEITEN: Wie Russel sagt, haben Facetten einige versteckte Probleme und sind nicht vollständig API-kompatibel mit ActiveSupport. Auf der anderen Seite ist ActiveSupport nicht so vollständig wie Facetten. Am Ende würde ich AS verwenden und die Randfälle in Ihrem Code lassen.
quelle
require 'facets/hash/except'
und es gibt keine "Probleme" (nicht sicher, welche Probleme sie sonst wären, außer nicht 100% AS API). Wenn Sie ein Rails-Projekt mit AS durchführen, ist dies sinnvoll, wenn nicht, hat Facets einen viel geringeren Platzbedarf.Anstatt Ruby zu patchen oder unnötigerweise große Bibliotheken einzuschließen, können Sie Verfeinerungen verwenden, wenn Sie Ruby 2 verwenden :
Sie können diese Funktion verwenden, ohne andere Teile Ihres Programms zu beeinträchtigen oder große externe Bibliotheken einzuschließen.
quelle
in reinem Rubin:
quelle
Siehe Ruby on Rails: Löschen Sie mehrere Hash-Schlüssel
quelle
each
würde das Array zurückgeben.Es war großartig, wenn delete das Löschpaar des Hashs zurückgibt. Ich mache das:
quelle
Dies ist eine einzeilige Methode, die jedoch nicht sehr gut lesbar ist. Empfehlen Sie stattdessen zwei Zeilen.
quelle
Hash#except
undHash#except!
wurden schon genug erwähnt. DieProc.new
Version ist, wie Sie erwähnen, nicht sehr lesbar und auch komplizierter alsuse_remaining_hash_for_something(begin hash.delete(:key); hash end)
. Vielleicht löschen Sie einfach diese Antwort.Mehrere Möglichkeiten, Key in Hash zu löschen. Sie können eine beliebige Methode von unten verwenden
Es gibt so viele Möglichkeiten, dass Sie sich das Ruby-Dokument von Hash hier ansehen können .
Vielen Dank
quelle
Dies würde auch funktionieren:
hash[hey] = nil
quelle