2016-09-06 17 views
6

Tôi có một phương pháp mà tôi muốn quyết định những gì cần trả lại trong một hàm bản đồ. Tôi biết rằng điều này có thể được thực hiện bằng cách gán một biến, nhưng đây là cách tôi mặc dù tôi có thể làm điều đó;`return` trong Ruby Array # map

def some_method(array) 
    array.map do |x| 
     if x > 10 
     return x+1 #or whatever 
     else 
     return x-1 
     end 
    end 
end 

này không làm việc như tôi mong đợi bởi vì lần đầu tiên return là hit, nó sẽ trả về từ phương pháp này, và không có trong các chức năng bản đồ, tương tự như cách trả lại được sử dụng trong chức năng đồ javascript của.

Có cách nào để đạt được cú pháp mong muốn của tôi không? Hoặc tôi có cần chỉ định điều này cho biến hay không và để nó treo ở cuối như sau:

def some_method(array) 
    array.map do |x| 
     returnme = x-1 
     if x > 10 
     returnme = x+1 #or whatever 
     end 
     returnme 
    end 
end 

Trả lời

12

Bạn không cần biến. Giá trị trả về của khối là giá trị của biểu thức cuối cùng được đánh giá trong nó. Trong trường hợp này, if.

def some_method(array) 
    array.map do |x| 
     if x > 10 
     x+1 
     else 
     x-1 
     end 
    end 
end 

Toán tử ba năm trông đẹp hơn, tôi nghĩ vậy. Thêm biểu thức-ish.

def some_method(array) 
    array.map do |x| 
    (x > 10) ? x+1 : x-1 
    end 
end 

Nếu bạn nhấn mạnh vào việc sử dụng return, thì bạn có thể sử dụng lambdas. Trong lambdas, return hoạt động như trong các phương thức thông thường.

def some_method(array) 
    logic = ->(x) { 
    if x > 10 
     return x + 1 
    else 
     return x - 1 
    end 
    } 
    array.map(&logic) 
end 

Biểu mẫu này hiếm khi được nhìn thấy. Nếu mã của bạn ngắn, chắc chắn nó có thể được viết lại dưới dạng biểu thức. Nếu mã của bạn dài và phức tạp đủ để đảm bảo nhiều điểm thoát, thì có lẽ bạn nên thử đơn giản hóa nó.

+0

Tốt! Tôi đã phải làm lại mã của tôi một chút, nhưng tôi tin rằng đây là một giải pháp tuyệt vời! – Automatico

+1

@ Cort3z: xem câu trả lời cập nhật :) –

15

Câu trả lời của Sergio rất tốt, nhưng đáng lưu ý là có từ khóa hoạt động theo cách bạn muốn return để hoạt động: next.

array.map do |x| 
    if x > 10 
    next x + 1 
    else 
    next x - 1 
    end 
end 

Đây không phải là việc sử dụng rất tốt next bởi vì, như Sergio đã chỉ ra, bạn không cần bất kỳ thứ gì ở đó. Tuy nhiên, bạn có thể sử dụng next để thể hiện nó gọn gàng hơn:

array.map do |x| 
    next x + 1 if x > 10 
    x - 1 
end 
+1

Điều đó thật tuyệt! Mã thực sự của tôi phức tạp hơn một chút so với ví dụ trên của tôi, vì vậy 'next' có thể là một giải pháp rất hay. Cá nhân tôi không thích tất cả điều này "ma thuật theo mặc định" hành vi của ruby. Nó là tốt đẹp để tuyên bố rõ ràng những gì đang xảy ra vì vậy nó dễ dàng hơn cho người tiếp theo để nhặt nó lên. – Automatico

+0

Câu trả lời tốt hơn nhiều! –