2012-06-14 12 views
11

Filtruję tablicę w ruby ​​i używam bloku .select, aby to zrobić. Warunki są wystarczająco skomplikowane, że pojedynczy blok linii jest ohydny, ale nie tak duży, więc oddzielna metoda wydaje się przesadą. Dlatego chcę użyć bloku wielowierszowego. Jednak nie jestem pewien składni.Ruby array.select blok multilinii

filtered_array = base_array.select do |elem| 
    return false if condition1 
    return false if condition2 
    return true 
end 

Powyższe jest oczywiście błędna jak return wychodzi metodę, a nie blok, ale daje wyobrażenie o tym, co szukam.

Mogę również użyć wielu instrukcji wyboru, ale wydaje się to zaciemniać to, co próbuję zrobić. Należy zauważyć, że powyższe warunki są wystarczająco skomplikowane, że użycie operatorów logicznych do ich wiązania powoduje bałagan.

+0

Można także użyć zmiennych tymczasowych. –

+0

@Anton zobacz moją edycję proszę. – Kyle

+0

Bloki w tablicach nie działają z instrukcjami powrotu (zwroty powracałyby z metody zawierającej blok), chyba że są to lambdy, które domyślnie blokują. Rozwiązaniem twojego konkretnego przypadku użycia jest ten, który dostarczył Kyle, ogólny byłby instrukcją if lub case, tak jak zetetic, i ogólnie, po prostu nie używaj zwrotów, aby powrócić z bloków, chyba że wiesz, że idą być lambdami, czyli przekształconymi w metody. –

Odpowiedz

20

Co chcesz jest next zamiast return.

+1

Działa to, jeśli chcę" zwrócić false ", ale nie, jeśli chcę" zwrócić true '. – AntonDelprado

+7

'next' może przyjąć wartość, podobnie jak" return ". 'next (true)' jest analogiczne do 'return (true)'. – rcrogers

6

Edytuj: Po prostu zobaczyłem: "używanie operatorów logicznych do wiązania ich powoduje bałagan". Czy możesz podać rzeczywiste warunki?

filtered_array = base_array.select do |elem| 
    condition1 && condition2 
end 
+0

Myślę, że ogólna koncepcja wymaga odpowiedzi, ale: '| elem | self.array1.include? elem.name' i inne jest trochę bardziej złożone 'elem.name.include? "some string" && self.other_array.include? (elem.name.sub ("jakiś ciąg", "inny ciąg")) ' – AntonDelprado

2

Wygląda to może być obsługiwane za pomocą instrukcji case:

filtered_array = base_array.select do |elem| 
    case 
    when condition1 
    false 
    when condition2 
    false 
    else 
    true 
    end 
end 
1

Należy prawdopodobnie wystarczy użyć:

next(true) 

Jednak jeśli nie jive z następnie to zrobić:

my_array.select do |x| 
    # bool = false ### optional, uncomment this if you prefer 
    if x.id == 1 
    bool = true 
    end 
    bool 
end 
Powiązane problemy