2011-07-08 41 views
54

Tôi muốn xóa mọi khóa khỏi mã băm ngoại trừ một khóa nhất định.Hash xóa tất cả ngoại trừ các phím cụ thể

Ví dụ:

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

Tôi muốn loại bỏ tất cả mọi thứ ngoại trừ "firstName" và/hoặc "Địa chỉ"

Cảm ơn

Trả lời

43

Một số tùy chọn khác:

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

Hoặc bạn có thể làm điều này:

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

Vì vậy, bạn có thể bây giờ chỉ cần nói:

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

Tôi thích sử dụng mảng để dễ dàng thêm các phím mới thay vì nhiều câu lệnh OR hơn. Phần mở rộng Hash cũng khá thú vị :) –

+1

Cảm ơn. Câu trả lời toàn diện hơn nhiều! – glarkou

+0

Đây có phải chỉ dành cho đường ray không? hoặc ruby ​​nói chung? – Fadi

6

Hash # chọn làm những gì bạn muốn:

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} 

Chỉnh sửa (để nhận xét):

giả sử h là băm của bạn ở trên:

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

Nếu tôi muốn chọn "tuổi" và "địa chỉ" từ ví dụ của mình thì sao? – glarkou

+0

Cảm ơn bạn rất nhiều! Đó là chính xác những gì tôi đang tìm kiếm. – glarkou

+0

Đã chấp nhận :) Cảm ơn bạn lần nữa – glarkou

213

Thật là một bout slice?

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

Câu hỏi không đề cập cụ thể đến Rails, nhưng nó được gắn thẻ như vậy. Đây là tùy chọn tốt nhất khi sử dụng Rails hoặc core_ext. –

+2

Vâng, đây là lý do tôi đề xuất 'slice'. –

+0

câu trả lời này phải là câu trả lời đầu tiên! –

1

Lấy cảm hứng từ câu trả lời Jake Dempsey, người ta này nên nhanh hơn cho băm lớn, vì nó chỉ đỉnh phím rõ ràng hơn là lặp qua toàn bộ băm:

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

Nếu bạn sử dụng Rails, hãy xem xét ActiveSupport except() phương pháp: 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

Ngoại trừ giữ tất cả mọi thứ ngoại trừ được đưa ra. Điều ngược lại câu hỏi là gì. –

0

Không Rails cần thiết để nhận được một mã rất ngắn gọn:

0.123.
keys = [ "firstName" , "address" ] 
# keys = hash.keys - (hash.keys - keys) # uncomment if needed to preserve hash order 
keys.zip(hash.values_at *keys).to_h 
Các vấn đề liên quan