2016-09-06 14 views
6

Mam metodę, w której chciałbym zdecydować, co zwrócić w funkcji mapy. Zdaję sobie sprawę, że można to zrobić, przypisując zmienną, ale tak właśnie mogłem to zrobić;`return` w 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 

To nie działa jak oczekuję, ponieważ po raz pierwszy return jest trafiony, to wraca z metody, a nie w funkcji map, podobnie jak powrót jest używany w funkcji map jest obsługa JavaScript.

Czy istnieje sposób na osiągnięcie pożądanej składni? Czy muszę przypisać to do zmiennej i pozostawić ją zwisającą na końcu w następujący sposób:

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

Odpowiedz

12

Nie potrzebujesz zmiennej. Wartość zwracana bloku jest wartością ostatniego wyrażenia w nim obliczonego. W tym przypadku if.

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

Ternary operator wyglądałby ładniej, jak sądzę. Więcej wyrazu - ach.

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

Jeśli nalegasz na używanie return, możesz użyć lambdas. W lambdas, return zachowuje się jak w normalnych metodach.

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

Formularz ten jest jednak rzadko widywany. Jeśli twój kod jest krótki, z pewnością można go przepisać jako wyrażeń. Jeśli twój kod jest długi i skomplikowany, by uzasadnić wiele punktów wyjścia, prawdopodobnie powinieneś spróbować go uprościć.

+0

Nice! Musiałem trochę zmodyfikować kod, ale uważam, że jest to świetne rozwiązanie! – Automatico

+1

@ Cort3z: sprawdź zaktualizowaną odpowiedź :) –

15

Sergio odpowiedź jest bardzo dobra, ale warto podkreślić, że istnieje jest słowo kluczowe, które działa w ten sposób chciał return pracować: next.

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

Nie jest to bardzo dobre wykorzystanie next ponieważ, jak Sergio wskazał, nie trzeba tam nic. Możesz jednak użyć funkcji next, aby wyrazić ją w bardziej zwięzły sposób:

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

To jest miłe! Mój aktualny kod jest nieco bardziej skomplikowany niż mój przykład powyżej, więc 'next' może być bardzo dobrym rozwiązaniem. Osobiście nie podoba mi się to zachowanie "rubinowej magii". Miło jest jednoznacznie określić, co się dzieje, aby następna osoba mogła łatwiej ją odebrać. – Automatico

+0

Znacznie lepsza odpowiedź! –