해시에 새 쌍을 추가하려면 다음을 수행하십시오.
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
해시에서 키를 삭제하는 비슷한 방법이 있습니까?
이것은 작동합니다 :
{:a => 1, :b => 2}.reject! { |k| k == :a } #=> {:b => 2}
그러나 나는 다음과 같은 것을 기대할 것입니다 :
{:a => 1, :b => 2}.delete!(:a) #=> {:b => 2}
반환 값은 나머지 해시이어야하므로 다음과 같은 작업을 수행 할 수 있습니다.
foo(my_hash.reject! { |k| k == my_key })
한 줄에.
답변
레일즈에는 예외 / 제외가 있습니다! 해당 키가 제거 된 해시를 반환하는 메서드 입니다. 이미 Rails를 사용하고 있다면, 자신 만의 버전을 만드는 것은 의미가 없습니다.
class Hash
# Returns a hash that includes everything but the given keys.
# hash = { a: true, b: false, c: nil}
# hash.except(:c) # => { a: true, b: false}
# hash # => { a: true, b: false, c: nil}
#
# This is useful for limiting a set of parameters to everything but a few known toggles:
# @person.update(params[:person].except(:admin))
def except(*keys)
dup.except!(*keys)
end
# Replaces the hash without the given keys.
# hash = { a: true, b: false, c: nil}
# hash.except!(:c) # => { a: true, b: false}
# hash # => { a: true, b: false }
def except!(*keys)
keys.each { |key| delete(key) }
self
end
end
답변
Oneliner 일반 루비, 루비> 1.9.x에서만 작동합니다.
1.9.3p0 :002 > h = {:a => 1, :b => 2}
=> {:a=>1, :b=>2}
1.9.3p0 :003 > h.tap { |hs| hs.delete(:a) }
=> {:b=>2}
Tap 메소드는 항상 호출 된 객체를 반환합니다 …
그렇지 않으면 필요한 경우 active_support/core_ext/hash
(모든 Rails 애플리케이션에서 자동으로 필요함) 필요에 따라 다음 방법 중 하나를 사용할 수 있습니다.
➜ ~ irb
1.9.3p125 :001 > require 'active_support/core_ext/hash' => true
1.9.3p125 :002 > h = {:a => 1, :b => 2, :c => 3}
=> {:a=>1, :b=>2, :c=>3}
1.9.3p125 :003 > h.except(:a)
=> {:b=>2, :c=>3}
1.9.3p125 :004 > h.slice(:a)
=> {:a=>1}
제외 는 블랙리스트 접근 방식을 사용하므로 인수로 나열된 모든 키를 제거 하고 slice 는 화이트리스트 접근 방식을 사용하므로 인수로 나열되지 않은 모든 키를 제거합니다. 주어진 해시를 수정 하는 메소드 ( except!
및 slice!
) 의 뱅 버전도 있지만 반환 값이 다르면 둘 다 해시를 반환합니다. 제거 된 키 slice!
와 다음에 대해 유지되는 키를 나타냅니다 except!
.
1.9.3p125 :011 > {:a => 1, :b => 2, :c => 3}.except!(:a)
=> {:b=>2, :c=>3}
1.9.3p125 :012 > {:a => 1, :b => 2, :c => 3}.slice!(:a)
=> {:b=>2, :c=>3}
답변
왜 사용하지 않습니까?
hash.delete(key)
답변
해시에서 키를 제거하고 Ruby에서 나머지 해시를 얻는 방법에는 여러 가지가 있습니다.
-
.slice
=> 선택한 키를 반환하고 원래 해시에서 삭제하지 않습니다. 사용slice!
당신이 키를 영구적으로 다른 사용을 간단하게 제거 할 경우slice
.2.2.2 :074 > hash = {"one"=>1, "two"=>2, "three"=>3} => {"one"=>1, "two"=>2, "three"=>3} 2.2.2 :075 > hash.slice("one","two") => {"one"=>1, "two"=>2} 2.2.2 :076 > hash => {"one"=>1, "two"=>2, "three"=>3}
-
.delete
=> 원래 해시에서 선택한 키를 삭제합니다 (하나의 키만 허용하고 하나는 허용하지 않습니다).2.2.2 :094 > hash = {"one"=>1, "two"=>2, "three"=>3} => {"one"=>1, "two"=>2, "three"=>3} 2.2.2 :095 > hash.delete("one") => 1 2.2.2 :096 > hash => {"two"=>2, "three"=>3}
-
.except
=> 나머지 키를 반환하지만 원래 해시에서 아무것도 삭제하지 않습니다. 사용except!
당신이 키를 영구적으로 다른 사용을 간단하게 제거 할 경우except
.2.2.2 :097 > hash = {"one"=>1, "two"=>2, "three"=>3} => {"one"=>1, "two"=>2, "three"=>3} 2.2.2 :098 > hash.except("one","two") => {"three"=>3} 2.2.2 :099 > hash => {"one"=>1, "two"=>2, "three"=>3}
-
.delete_if
=> 값을 기준으로 키를 제거해야하는 경우. 원래 해시에서 일치하는 키를 분명히 제거합니다.2.2.2 :115 > hash = {"one"=>1, "two"=>2, "three"=>3, "one_again"=>1} => {"one"=>1, "two"=>2, "three"=>3, "one_again"=>1} 2.2.2 :116 > value = 1 => 1 2.2.2 :117 > hash.delete_if { |k,v| v == value } => {"two"=>2, "three"=>3} 2.2.2 :118 > hash => {"two"=>2, "three"=>3}
-
.compact
=>nil
해시에서 모든 값 을 제거하는 데 사용됩니다 . 값을 영구적으로compact!
제거 하려면 사용하십시오 .nil
그렇지 않으면 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 => {"one"=>1, "two"=>2, "three"=>3}
Ruby 2.2.2를 기반으로 한 결과.
답변
순수 루비 (레일 없음)를 사용하려면 확장 메소드를 작성하지 말고 (한두 곳에서만 필요하며, 수많은 메소드로 네임 스페이스를 오염시키지 않으려는 경우) 원하지 않습니다. 해시를 제자리에서 편집하십시오 (즉, 나와 같은 기능적 프로그래밍의 팬입니다).
>> x = {:a => 1, :b => 2, :c => 3}
=> {:a=>1, :b=>2, :c=>3}
>> x.select{|x| x != :a}
=> {:b=>2, :c=>3}
>> x.select{|x| ![:a, :b].include?(x)}
=> {:c=>3}
>> x
=> {:a=>1, :b=>2, :c=>3}
답변
#in lib/core_extensions.rb
class Hash
#pass single or array of keys, which will be removed, returning the remaining hash
def remove!(*keys)
keys.each{|key| self.delete(key) }
self
end
#non-destructive version
def remove(*keys)
self.dup.remove!(*keys)
end
end
#in config/initializers/app_environment.rb (or anywhere in config/initializers)
require 'core_extensions'
.remove가 키를 제거한 상태로 해시 사본을 반환하고 제거하도록 이것을 설정했습니다! 해시 자체를 수정합니다. 이것은 루비 규칙과 일치합니다. 예를 들어 콘솔에서
>> hash = {:a => 1, :b => 2}
=> {:b=>2, :a=>1}
>> hash.remove(:a)
=> {:b=>2}
>> hash
=> {:b=>2, :a=>1}
>> hash.remove!(:a)
=> {:b=>2}
>> hash
=> {:b=>2}
>> hash.remove!(:a, :b)
=> {}
답변
보석 except!
에서 사용할 수 있습니다 facets
:
>> require 'facets' # or require 'facets/hash/except'
=> true
>> {:a => 1, :b => 2}.except(:a)
=> {:b=>2}
원래 해시는 변경되지 않습니다.
편집 : Russel이 말했듯이 패싯에는 숨겨진 문제가 있으며 ActiveSupport와 완전히 API 호환되지 않습니다. 반면에 ActiveSupport는 패싯만큼 완벽하지 않습니다. 결국, 나는 AS를 사용하고 코드에서 가장 중요한 사례를 보자.