哈希删除除特定键以外的所有键


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"
     }
 ]
}

我想删除除“名字”和/或“地址”之外的所有内容

谢谢

Answers:


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

1
谢谢。更全面的答案!
glarkou

这仅用于导轨吗?还是红宝石?
法迪

276

slice

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

9
这个问题并没有特别提到Rails,但是它被这样标记。当使用Rails或core_ext时,这是最佳选择。
Caleb Hearth

3
是的,这就是我建议的原因slice
Mario Uher

这个答案应该是第一个!
mmike '16

@DimaMelnik哈希本质上没有命令。
约书亚·品特

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.