2011-07-08 67 views
54

我想除键之外的其他所有键。哈希删除除特定键之外的所有键

例如:

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

我想删除除 “名字” 一切和/或 “地址”

感谢

回答

43

其他一些选项:

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语句。哈希扩展也很酷:) –

+1

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

+0

这只适用于导轨吗?或一般的红宝石? – Fadi

6

哈希#选择你想要做什么:

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" } 
+0

如果我想从我的示例中选择“年龄”和“地址”,该怎么办? – glarkou

+0

非常感谢!那正是我所期待的。 – glarkou

+0

接受:)再次感谢 – glarkou

213

什么是回合slice

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

这个问题没有具体提到Rails,但它被标记为这样。当使用Rails或core_ext时,这是最好的选择。 –

+2

是的,这是我建议'切片'的原因。 –

+0

这个答案应该是第一个! –

1

由杰克·登普西的回答启发,这应该是大散列的速度更快,因为它仅峰值明确的钥匙,而不是在整个哈希迭代:

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 
4

如果您使用Rails的,请考虑的ActiveSupport except()方法: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 } 
+10

除了保留一切,除了给定。问题的相反。 –

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