2013-01-05 6 views
8

Ai đó có thể giúp tôi rút ngắn phương pháp sau không? Tôi bắt đầu với điều này, mà tôi thích tốt:Bao gồm có điều kiện của cặp khóa-giá trị trong một băm

def self.some_hash 
    { "foo" => "bar" } 
end 

Bây giờ tôi muốn thêm một khóa tùy chọn. Cú pháp tersest tôi có thể nghĩ là thế này:

def self.some_hash(some_key=nil) 
    answer = { "foo" => "bar" } 
    answer[some_key] = "yucky, long-winded syntax" if some_key 
    answer 
end 

Phương pháp điều chỉnh hoạt động, nhưng tôi không hài lòng với sự lãng phí mực ảo. Có cách nào để rút ngắn nó không? Tôi nhận ra người ta có thể sử dụng một toán tử bậc ba trên băm chữ, nhưng điều đó sẽ buộc (tôi nghĩ) sự lặp lại cặp "foo" => "bar" trên mỗi nhánh của điều kiện, mà cũng hơi kém hơn nguyên sơ.

+0

"giúp tôi rút ngắn phương pháp sau" là tặng rằng điều này nên ở trên codereview.stackexchange.com, nơi họ thực hiện các đánh giá và trợ giúp với việc tái cấu trúc và tối ưu hóa. –

+0

Rất tiếc khi thấy câu hỏi này bị đóng, khi nó thực sự hỏi, "Làm thế nào để tôi có điều kiện bao gồm cặp khóa/giá trị trong một băm?". Tôi đã viết một câu trả lời ở nơi khác bằng cách sử dụng [toán tử double-splat của Ruby 2.0] (http://stackoverflow.com/a/37474217/122087). –

+0

@PaulAJungwirth, tôi đoán nó đã bị đóng vì tôi chỉ muốn cải thiện mã làm việc. Tôi có thể đã tạo ra một số cú pháp rác và sau đó nói rằng nó không hoạt động, và tất cả sẽ tốt trong SO. Đó là một mẹo tuyệt vời về toán tử **! Cảm ơn <--- nản lòng 'cảm ơn trong một bình luận là một cái câm, chuẩn mực xung quanh đây, nhưng -> CẢM ƠN! – danh

Trả lời

8
def self.some_hash(some_key = nil) 
    {"foo" => "bar"}.merge(some_key ? {some_key => "yucky, long-winded syntax"} : {}) 
end 

Hoặc, nếu sửa đổi băm gốc,

def self.some_hash(some_key = nil) 
    {"foo" => "bar"} 
    .tap{|h| h.merge!(some_key => "yucky, long-winded syntax") if some_key} 
end 

Hoặc, có thể bạn có thể làm điều đó một cách chặt chẽ để ban đầu của bạn:

def self.some_hash(some_key = nil) 
    {"foo" => "bar"} 
    .tap{|h| h[some_key] = "yucky, long-winded syntax" if some_key} 
end 
+1

Ồ. Điều đó thật tuyệt. Ngắn, như @Kyle, và rõ ràng hơn. Cũng tốt vì nó bao gồm, thay vì loại bỏ, có điều kiện. Cảm ơn. – danh

+0

+1 cho đoạn mã đầu tiên (chức năng), tôi muốn ở xa 'tap' càng tốt (IMHO nó khuyến khích mã không rõ ràng, bắt buộc) – tokland

+0

cảm ơn. cũng đánh giá cao việc học về .tap. Câu hỏi meta: cảm ơn bạn đã chỉnh sửa câu hỏi của mình. có một số bước tôi phải thực hiện để chấp nhận chỉnh sửa không? – danh

1

tôi không thực sự thích nó nhưng điều này là khá ngắn gọn (và khó hiểu)

def self.some_hash(some_key=nil) 
    Hash[[["foo", "bar"], [some_key, "some value"]].select(&:first)] 
end 

Đây có thể là một chút tốt hơn.

def self.some_hash(some_key=nil) 
    {"foo" => "bar", some_key => "some_value"}.keep_if{ |k, _| k } 
end 

Hash#keep_if

+0

Cảm ơn. Đó là ít nhất một +1 cho ngắn gọn. Sẽ chờ một chút để xem những gì khác được đề xuất. – danh

+0

@danh Tôi đã thêm một cái nữa cho bạn mà tôi nghĩ là tốt hơn một chút. – Kyle

+0

Tôi ước tôi có thể bỏ phiếu hai lần. Tôi nghĩ ý tưởng thứ hai của bạn rõ ràng hơn và ngắn gọn, nhưng @sawa giúp chúng tôi không thực hiện thêm + xóa điều kiện. Không bao giờ nghe nói về keep_if, và đánh giá cao việc học tập đó, quá! – danh