Ich habe einen Hash, der ungefähr so aussieht:
params = { :irrelevant => "A String",
:choice1 => "Oh look, another one",
:choice2 => "Even more strings",
:choice3 => "But wait",
:irrelevant2 => "The last string" }
Und ich möchte auf einfache Weise alle Schlüssel ablehnen, die nicht Auswahl + int sind. Es könnte Wahl1 oder Wahl1 bis Wahl10 sein. Es variiert.
Wie kann ich die Tasten nur mit der Wortwahl und einer Ziffer oder Ziffern nach ihnen auswählen?
Bonus:
Verwandeln Sie den Hash in eine Zeichenfolge mit Tabulator (\ t) als Trennzeichen. Ich habe das gemacht, aber es dauerte mehrere Codezeilen. Normalerweise können Meister-Rubiker dies in einer oder mehreren Zeilen tun.
Antworten:
Auf ursprüngliche Antwort bearbeiten : Obwohl dies die Antwort (zum Zeitpunkt dieses Kommentars) die ausgewählte Antwort ist, ist die ursprüngliche Version dieser Antwort veraltet.
Ich füge hier ein Update hinzu, damit andere nicht von dieser Antwort abgelenkt werden, wie ich es getan habe.
Wie in der anderen Antwort erwähnt, hat Ruby> = 2.5 die
Hash#slice
Methode hinzugefügt , die zuvor nur in Rails verfügbar war.Beispiel:
Ende der Bearbeitung. Was folgt, ist die ursprüngliche Antwort, die ich für nützlich halte, wenn Sie Ruby <2.5 ohne Rails verwenden, obwohl ich mir vorstelle, dass dieser Fall derzeit ziemlich ungewöhnlich ist.
Wenn Sie Ruby verwenden, können Sie die
select
Methode verwenden. Sie müssen den Schlüssel von einem Symbol in einen String konvertieren, um die Regexp-Übereinstimmung durchzuführen. Dadurch erhalten Sie einen neuen Hash mit nur den darin enthaltenen Optionen.oder Sie können
delete_if
den vorhandenen Hash verwenden und ändern, zoder wenn es nur die Schlüssel und nicht die gewünschten Werte sind, können Sie Folgendes tun:
und dies gibt dem nur ein Array der Schlüssel, z
[:choice1, :choice2, :choice3]
quelle
.select
ist.reject
, wenn dies Ihren Code idiomatischer macht.#slice
Weg funktioniert bei mir auf 2.5.3 auch ohne aktive Unterstützung.In Ruby ist die Auswahl von Hash # eine richtige Option. Wenn Sie mit Rails arbeiten, können Sie Hash # Slice und Hash # Slice! Verwenden. zB (Schienen 3.2.13)
quelle
Am einfachsten ist es, das
gem 'activesupport'
(odergem 'active_support'
) einzuschließen .Dann müssen Sie in Ihrer Klasse nur noch
und anzurufen
Ich glaube, es lohnt sich nicht, andere Funktionen zu deklarieren, die möglicherweise Fehler aufweisen, und es ist besser, eine Methode zu verwenden, die in den letzten Jahren optimiert wurde.
quelle
Am einfachsten ist es, den Edelstein 'activesupport' (oder den Edelstein 'active_support') einzuschließen.
params.slice(:choice1, :choice2, :choice3)
quelle
Wenn Sie mit Schienen arbeiten und die Schlüssel in einer separaten Liste haben, können Sie die
*
Notation verwenden:Wie in anderen Antworten angegeben, können Sie auch
slice!
den vorhandenen Hash ändern (und den gelöschten Schlüssel / die gelöschten Werte zurückgeben).quelle
Dies ist eine Zeile, um die vollständige ursprüngliche Frage zu lösen:
Die meisten der oben genannten Lösungen lösen jedoch einen Fall, in dem Sie die Schlüssel im
slice
Voraus kennen müssen, indem Sie einen einfachen regulären Ausdruck verwenden.Hier ist ein weiterer Ansatz , der für einfache und komplexere Anwendungsfälle funktioniert und zur Laufzeit ausgetauscht werden kann
Dies ermöglicht nicht nur eine komplexere Logik beim Abgleichen der Schlüssel oder Werte, sondern ist auch einfacher zu testen, und Sie können die Übereinstimmungslogik zur Laufzeit austauschen.
Ex, um das ursprüngliche Problem zu lösen:
quelle
Mit
Hash::select
:quelle
Wenn Sie den verbleibenden Hash möchten:
oder wenn Sie nur die Schlüssel wollen:
quelle
Setzen Sie dies in einen Initialisierer
Dann können Sie tun
oder
quelle
quelle
Was die Bonusfrage betrifft:
Wenn Sie eine solche
#select
Methode ausgegeben haben (Liste der 2-Element-Arrays):Nehmen Sie dann einfach dieses Ergebnis und führen Sie Folgendes aus:
Wenn Sie eine Ausgabe von einer
#delete_if
solchen Methode (Hash) haben:dann:
quelle
map
nimmt Block als Argument. Sie können einen Block im laufenden Betrieb mit einer&:method
Konstruktion erstellen, die einen Block erstellen würde{|v| v.method }
. In meinem Fall&:last
wurde ein Array-Argument (2-Element-Array) aufgerufen. Wenn Sie damit spielen möchten, überprüfen Sie zuerst, welches Argument Sie in Block erhalten (erhalten Sie 1 Argument, dekonstruieren Sie es nicht in mehrere Argumente!) Und versuchen Sie, 1 Methode zu finden (mit der Sie keine Methoden verketten können&:method
), die Ihnen das zurückgibt, was Sie sind wollen. Wenn es möglich ist, können Sie die Verknüpfung verwenden. Wenn nicht, benötigen Sie einen vollständigen Blockquelle
Ich hatte ein ähnliches Problem. In meinem Fall war die Lösung ein Einzeiler, der auch dann funktioniert, wenn die Schlüssel keine Symbole sind, aber Sie müssen die Kriterienschlüssel in einem Array haben
Ein anderes Beispiel
quelle