Para adicionar um novo par ao Hash, eu faço:
Existe uma maneira semelhante de excluir uma chave do Hash?
mas eu esperaria ter algo como:
É importante que o valor retornado seja o hash restante, para que eu possa fazer coisas como:
em uma linha.
Você sempre pode estender (abrir em tempo de execução) o Hash interno para adicionar esse método personalizado, se você realmente precisar.
— dbryson
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.
Você não precisa usar a pilha completa do Rails. Você pode incluir o ActiveSupport em qualquer aplicativo Ruby.
— Fryie 27/09/2013
Para adicionar à resposta de Fryie, você nem precisa carregar todo o ActiveSupport; você pode apenas incluí-los entãorequire "active_support/core_ext/hash/except"
tarde demais para edit: eu quis dizer "incluem a jóia" não "incluí-los"
@ GMA: quando seus cinco minutos de edição terminam, você sempre pode copiar, excluir, modificar e repassar um comentário.
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!e slice!) que modificam o hash especificado, mas seu valor de retorno é diferente, ambos retornam um hash. Representa as chaves removidas slice!e as chaves mantidas para except!:
+1 Vale ressaltar que esse método é destrutivo h. Hash#exceptnão modificará o hash original.
Use h.dup.tap { |hs| hs.delete(:a) }para evitar modificar o hash original.
— Magicode 13/11/2018
@ dbryson: Concordo que às vezes não vale a pena. Eu só quero saber por que há merge, merge!, delete, mas não detele!...
se você realmente precisa dele como um liner:foo(hash.delete(key) || hash)
— Bert Goethals
Seria mais consistente com as convenções de Ruby se deletese não modificar seu parâmetro e se delete!existiu e fez modificar seu parâmetro.
Isso não retorna o hash restante, conforme mencionado na pergunta, retornará o valor associado à chave excluída.
— MhdSyrwan 9/07
delete retorna a chave, mas também altera o hash. Quanto ao motivo pelo qual não há exclusão !, meu palpite é que, semanticamente, não faz sentido chamar delete em algo e na verdade não o exclui. chamar hash.delete () em vez de hash.delete! () seria um no-op.
— eggmatters 7/08/2015
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. Use slice!se você deseja remover as chaves permanentemente ou use simple slice.
.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. Use except!se você deseja remover as chaves permanentemente ou use simple except.
.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 os nilvalores do hash. Use compact!se você deseja remover os nilvalores permanentemente ou use simple compact.
2.2.2 :119 > hash = {"one"=>1, "two"=>2, "three"=>3, "nothing"=>nil, "no_value"=>nil}
=> {"one"=>1, "two"=>2, "three"=>3, "nothing"=>nil, "no_value"=>nil}
2.2.2 :120 > hash.compact
Resultados baseados em Ruby 2.2.2.
— techdreams
slicee exceptsão adicionados usando ActiveSupport::CoreExtensions::Hash. Eles não fazem parte do núcleo do Ruby. Eles podem ser usados ​​porrequire 'active_support/core_ext/hash'
— Madis Nõmme 9/10
Como o Ruby 2.5 Hash#sliceestá na biblioteca padrão. ruby-doc.org/core-2.5.0/Hash.html#method-i-slice Yay!
— Madis Nõmme
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':
— Yura Taras
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
Você pode usar a except!partir da facetsgema:
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.
Apenas 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.
Atualmente, o @trans ActiveSupport também possui uma área muito pequena, e você pode exigir apenas partes dela. Assim como facetas, mas com muito mais olhos nele (então suponho que receba melhores críticas).
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.
em Ruby puro:
Veja Ruby on Rails: Exclua várias chaves de hash
keys_to_delete.each {| k | hash.delete (k)} é muito mais rápido para grandes conjuntos de dados. me corrija se estiver errado.
— Vignesh Jayavel
@VigneshJayavel, você está certo, mas o OP queria que o hash fosse retornado. eachretornaria a matriz.
Foi ótimo se delete retornar o par de exclusão do hash. Eu estou fazendo isto:
— frenesim
Essa é uma maneira de fazer uma linha, mas não é muito legível. Recomenda o uso de duas linhas.
— the_minted
Hash#excepte Hash#except!já foram mencionados o suficiente. A Proc.newversão não é muito legível como você mencionou e também é mais complicada do que use_remaining_hash_for_something(begin hash.delete(:key); hash end). Talvez apenas exclua esta resposta.
Encurtou minha resposta e removeu o que já havia sido dito. Mantendo minha resposta junto com seu comentário, porque eles respondem à pergunta e fazem boas recomendações para uso.
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 .
— Ketan Mangukiya
Isso também funcionaria: hash[hey] = nil
— fdghdfg
h = {: a => 1,: b => 2,: c => 3}; h [: a] = nulo; h.each {| k, v | coloca k} Não é o mesmo que: h = {: a => 1,: b => 2,: c => 3}; h.delete (: a); h.each {| k, v | puts k}
— obaqueiro
Remover uma chave de um hash não é o mesmo que remover o valor de uma chave de um hash. Como isso pode levar as pessoas a confundir, seria melhor remover esta resposta.