Para adicionar um novo par ao Hash, eu faço:
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
Existe uma maneira semelhante de excluir uma chave do Hash?
Isso funciona:
{:a => 1, :b => 2}.reject! { |k| k == :a } #=> {:b => 2}
mas eu esperaria ter algo como:
{:a => 1, :b => 2}.delete!(:a) #=> {:b => 2}
É importante que o valor retornado seja o hash restante, para que eu possa fazer coisas como:
foo(my_hash.reject! { |k| k == my_key })
em uma linha.
ruby-on-rails
ruby
ruby-on-rails-3
hashmap
ruby-hash
Misha Moroshko
fonte
fonte
Respostas:
O Rails possui um exceto / exceto! método que retorna o hash com essas chaves removidas. Se você já está usando o Rails, não faz sentido criar sua própria versão disso.
fonte
require "active_support/core_ext/hash/except"
Oneliner plain ruby, funciona apenas com ruby> 1.9.x:
Toque método sempre retorna o objeto no qual é chamado ...
Caso contrário, se você solicitou
active_support/core_ext/hash
(o que é automaticamente necessário em todos os aplicativos Rails), você pode usar um dos seguintes métodos, dependendo de suas necessidades:exceto utiliza uma abordagem de lista negra, por isso remove todas as chaves listadas como args, enquanto a fatia usa uma abordagem de lista de permissões, por isso remove todas as chaves que não estão listadas como argumentos. Também existe a versão bang desses métodos (
except!
eslice!
) que modificam o hash especificado, mas seu valor de retorno é diferente, ambos retornam um hash. Representa as chaves removidasslice!
e as chaves mantidas paraexcept!
:fonte
h
.Hash#except
não modificará o hash original.h.dup.tap { |hs| hs.delete(:a) }
para evitar modificar o hash original.Por que não usar:
fonte
merge
,merge!
,delete
, mas nãodetele!
...foo(hash.delete(key) || hash)
delete
se não modificar seu parâmetro e sedelete!
existiu e fez modificar seu parâmetro.Existem várias maneiras de remover uma chave de um hash e obter o restante no Ruby.
.slice
=> Ele retornará as teclas selecionadas e não as excluirá do hash original. Useslice!
se você deseja remover as chaves permanentemente ou use simpleslice
..delete
=> Ele excluirá as chaves selecionadas do hash original (ele pode aceitar apenas uma chave e não mais de uma)..except
=> Ele retornará as chaves restantes, mas não excluirá nada do hash original. Useexcept!
se você deseja remover as chaves permanentemente ou use simpleexcept
..delete_if
=> Caso você precise remover uma chave com base em um valor. Obviamente, ele removerá as chaves correspondentes do hash original..compact
=> É usado para remover todos osnil
valores do hash. Usecompact!
se você deseja remover osnil
valores permanentemente ou use simplecompact
.Resultados baseados em Ruby 2.2.2.
fonte
slice
eexcept
são adicionados usandoActiveSupport::CoreExtensions::Hash
. Eles não fazem parte do núcleo do Ruby. Eles podem ser usados porrequire 'active_support/core_ext/hash'
Hash#slice
está na biblioteca padrão. ruby-doc.org/core-2.5.0/Hash.html#method-i-slice Yay!Se você deseja usar Ruby puro (sem Rails), não deseja criar métodos de extensão (talvez você precise disso apenas em um ou dois lugares e não queira poluir o espaço de nome com vários métodos) e não deseja editar o hash no lugar (ou seja, você é fã de programação funcional como eu), pode 'selecionar':
fonte
Eu configurei isso para que .remove retorne uma cópia do hash com as chaves removidas enquanto remove! modifica o próprio hash. Isso está de acordo com as convenções ruby. por exemplo, do console
fonte
Você pode usar a
except!
partir dafacets
gema:O hash original não muda.
EDIT: como diz Russel, as facetas têm alguns problemas ocultos e não são completamente compatíveis com a API do ActiveSupport. Por outro lado, o ActiveSupport não é tão completo quanto as facetas. No final, eu usaria o AS e deixaria os casos extremos no seu código.
fonte
require 'facets/hash/except'
e os seus não são "problemas" (não tenho certeza de quais problemas eles seriam, a não ser 100% AS API). Se você estiver executando um projeto Rails usando o AS, faz sentido; caso contrário, o Facets terá uma área de cobertura muito menor.Em vez de aplicar patches em macacos ou incluir desnecessariamente grandes bibliotecas, você pode usar refinamentos se estiver usando o Ruby 2 :
Você pode usar esse recurso sem afetar outras partes do seu programa ou precisar incluir grandes bibliotecas externas.
fonte
em Ruby puro:
fonte
Veja Ruby on Rails: Exclua várias chaves de hash
fonte
each
retornaria a matriz.Foi ótimo se delete retornar o par de exclusão do hash. Eu estou fazendo isto:
fonte
Essa é uma maneira de fazer uma linha, mas não é muito legível. Recomenda o uso de duas linhas.
fonte
Hash#except
eHash#except!
já foram mencionados o suficiente. AProc.new
versão não é muito legível como você mencionou e também é mais complicada do queuse_remaining_hash_for_something(begin hash.delete(:key); hash end)
. Talvez apenas exclua esta resposta.Várias maneiras de excluir Key in Hash. você pode usar qualquer método abaixo
Há tantas maneiras, você pode consultar o documento Ruby do Hash aqui .
Obrigado
fonte
Isso também funcionaria:
hash[hey] = nil
fonte