Aby dodać nową parę do Hash, robię:
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
Czy istnieje podobny sposób na usunięcie klucza z Hash?
To działa:
{:a => 1, :b => 2}.reject! { |k| k == :a } #=> {:b => 2}
ale oczekiwałbym czegoś takiego:
{:a => 1, :b => 2}.delete!(:a) #=> {:b => 2}
Ważne jest, aby zwracaną wartością był pozostały skrót, więc mogłem wykonywać następujące czynności:
foo(my_hash.reject! { |k| k == my_key })
w jednej linii.
ruby-on-rails
ruby
ruby-on-rails-3
hashmap
ruby-hash
Misza Moroszko
źródło
źródło
Odpowiedzi:
Railsy mają wyjątek / wyjątek! Metoda, która zwraca skrót z usuniętymi kluczami. Jeśli już używasz Railsów, nie ma sensu tworzyć własnej wersji tego.
źródło
require "active_support/core_ext/hash/except"
Oneliner zwykły rubin, działa tylko z ruby> 1.9.x:
Metoda dotknij zawsze zwraca obiekt, na który jest wywoływany ...
W przeciwnym razie, jeśli jest to wymagane
active_support/core_ext/hash
(co jest automatycznie wymagane w każdej aplikacji Railsowej), możesz użyć jednej z następujących metod w zależności od potrzeb:oprócz wykorzystuje podejście z czarnej listy, więc usuwa wszystkie klucze wymienione jako argumenty, a slice używa podejścia z białej listy, więc usuwa wszystkie klucze, które nie są wymienione jako argumenty. Istnieje również wersja Bang tej metody (
except!
islice!
), która modyfikuje dany skrót, ale ich wartość zwracana jest inna, obie zwracają skrót. Reprezentuje usunięte kluczeslice!
i klucze przechowywane dlaexcept!
:źródło
h
.Hash#except
nie zmodyfikuje oryginalnego skrótu.h.dup.tap { |hs| hs.delete(:a) }
aby uniknąć modyfikacji oryginalnego skrótu.Dlaczego nie po prostu użyć:
źródło
merge
,merge!
,delete
, ale niedetele!
...foo(hash.delete(key) || hash)
delete
nie nie zmodyfikować jego parametry, a jeślidelete!
istniał i tak zmodyfikować jego parametry.Istnieje wiele sposobów na usunięcie klucza z skrótu i uzyskanie pozostałego skrótu w Ruby.
.slice
=> Zwróci wybrane klucze i nie usunie ich z oryginalnego skrótu. Użyj,slice!
jeśli chcesz usunąć klucze na stałe, użyj prostegoslice
..delete
=> Spowoduje to usunięcie wybranych kluczy z oryginalnego skrótu (może zaakceptować tylko jeden klucz i nie więcej niż jeden)..except
=> Zwróci pozostałe klucze, ale nie usunie niczego z oryginalnego skrótu. Użyj,except!
jeśli chcesz usunąć klucze na stałe, użyj prostegoexcept
..delete_if
=> W przypadku, gdy musisz usunąć klucz na podstawie wartości. Oczywiście usunie pasujące klucze z oryginalnego skrótu..compact
=> Służy do usuwania wszystkichnil
wartości z mieszania. Użyj,compact!
jeśli chcesznil
trwale usunąć wartości, w innym przypadku użyj prostegocompact
.Wyniki oparte na Ruby 2.2.2.
źródło
slice
iexcept
są dodawane przy użyciuActiveSupport::CoreExtensions::Hash
. Nie są częścią rdzenia Ruby. Mogą z nich korzystaćrequire 'active_support/core_ext/hash'
Hash#slice
znajduje się w standardowej bibliotece. ruby-doc.org/core-2.5.0/Hash.html#method-i-slice Yay!Jeśli chcesz używać czystego Ruby (bez Railsów), nie chcesz tworzyć metod rozszerzeń (być może potrzebujesz tego tylko w jednym lub dwóch miejscach i nie chcesz zanieczyszczać przestrzeni nazw tonami metod) i nie chcesz edytować skrót w miejscu (tzn. jesteś fanem programowania funkcjonalnego takiego jak ja), możesz „wybrać”:
źródło
Skonfigurowałem to tak, aby .remove zwrócił kopię skrótu z usuniętymi kluczami podczas usuwania! modyfikuje sam skrót. Jest to zgodne z konwencjami rubinowymi. np. z konsoli
źródło
Możesz użyć
except!
zfacets
klejnotu:Oryginalny skrót nie zmienia się.
EDYCJA: jak mówi Russel, aspekty mają pewne ukryte problemy i nie są całkowicie kompatybilne z API z ActiveSupport. Z drugiej strony ActiveSupport nie jest tak kompletny jak aspekty. Na koniec użyłbym AS i pozwoliłbym, by w twoim kodzie były małe litery.
źródło
require 'facets/hash/except'
i nie są to „problemy” (nie jestem pewien, jakie problemy i tak by były, poza tym, że nie 100% AS API). Jeśli wykonujesz projekt Railsowy przy użyciu AS ma sens, jeśli nie, Facets ma znacznie mniejszą powierzchnię.Zamiast łatania małp lub niepotrzebnego dołączania dużych bibliotek, możesz użyć udoskonaleń, jeśli używasz Ruby 2 :
Możesz korzystać z tej funkcji bez wpływu na inne części programu lub konieczności dołączania dużych bibliotek zewnętrznych.
źródło
w czystym Ruby:
źródło
Zobacz Ruby on Rails: Usuń wiele kluczy skrótu
źródło
each
zwróci tablicę.Świetnie było, jeśli funkcja delete zwraca parę usuwania z mieszania. Robię to:
źródło
Jest to jeden wiersz, aby to zrobić, ale nie jest bardzo czytelny. Polecam zamiast tego użyć dwóch linii.
źródło
Hash#except
iHash#except!
zostały już wystarczająco wspomniane.Proc.new
Wersja nie jest bardzo czytelna, jak wspomniałeś, a także bardziej skomplikowane niżuse_remaining_hash_for_something(begin hash.delete(:key); hash end)
. Może po prostu usuń tę odpowiedź.Wiele sposobów usuwania klucza w skrócie. możesz użyć dowolnej z poniższych metod
Jest tak wiele sposobów, możesz spojrzeć na Ruby doc Hash tutaj .
Dziękuję Ci
źródło
Działa to również:
hash[hey] = nil
źródło