特定のキーを除くすべてをハッシュ削除


83

特定のキーを除くすべてのキーをハッシュから削除したいと思います。

例えば:

{
 "firstName": "John",
 "lastName": "Smith",
 "age": 25,
 "address":
 {
     "streetAddress": "21 2nd Street",
     "city": "New York",
     "state": "NY",
     "postalCode": "10021"
 },
 "phoneNumber":
 [
     {
       "type": "home",
       "number": "212 555-1234"
     },
     {
       "type": "fax",
       "number": "646 555-4567"
     }
 ]
}

「firstName」や「address」以外のすべてを削除したい

ありがとう

回答:


50

他のいくつかのオプション:

h.select {|k,v| ["age", "address"].include?(k) }

または、これを行うことができます:

class Hash
  def select_keys(*args)
    select {|k,v| args.include?(k) }
  end
end

だからあなたは今ただ言うことができます:

h.select_keys("age", "address")

1
配列を使用するのが好きなので、ORステートメントを増やす代わりに、新しいキーをすばやく簡単に追加できます。ハッシュ拡張もちょっとクールです:)
Jake Dempsey 2011

1
ありがとう。はるかに包括的な答え!
glarkou 2011

これはレール専用ですか?または一般的にルビー?
ファディ2016年

276

どうsliceですか?

hash.slice('firstName', 'lastName')
 # => { 'firstName' => 'John', 'lastName' => 'Smith' }

9
質問はRailsについて具体的に言及していませんでしたが、そのようにタグ付けされています。これは、Railsまたはcore_extを使用する場合に最適なオプションです。
カレブハース2012

3
はい、これが私が提案した理由ですslice
Mario Uher 2012

この答えは最初のものでなければなりません!
mmike 2016

@DimaMelnikハッシュには本質的に順序がありません。
Joshua Pinter 2018

2
Hash#sliceは純粋なRubyになり、Railsは必要ありません。
アキム

6

Hash#selectはあなたが望むことをします:

   h = { "a" => 100, "b" => 200, "c" => 300 }
   h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
   h.select {|k,v| v < 200}  #=> {"a" => 100}

編集(コメント用):

hが上記のハッシュであると仮定します。

h.select {|k,v| k == "age" || k == "address" }

例から「年齢」と「住所」を選択したい場合はどうすればよいですか?
glarkou 2011

2

Railsを使用する場合は、ActiveSupportexcept()メソッドを検討してください:http://apidock.com/rails/Hash/except

hash = { a: true, b: false, c: nil}
hash.except!(:c) # => { a: true, b: false}
hash # => { a: true, b: false }

20
与えられたものを除いてすべてを保持することを除いて。質問の逆です。
Christopher Oezbek 2015年

1

Jake Dempseyの答えに触発されて、これはハッシュ全体を反復処理するのではなく、明示的なキーのみをピークにするため、大きなハッシュに対してより高速になるはずです。

class Hash
  def select_keys(*args)
    filtered_hash = {}
    args.each do |arg|
      filtered_hash[arg] = self[arg] if self.has_key?(arg)
    end
    return filtered_hash
  end
end

0

非常に簡潔なコードを取得するためにRailsは必要ありません。

keys = [ "firstName" , "address" ]
# keys = hash.keys - (hash.keys - keys) # uncomment if needed to preserve hash order
keys.zip(hash.values_at *keys).to_h

0
hash = { a: true, b: false, c: nil }
hash.extract!(:c) # => { c: nil }
hash # => { a: true, b: false }

これにより、指定されたキーが含まれるのではなく、指定されたキーが除外されます。違いは微妙ですが重要です
BKSpurgeon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.