2013-03-14 11 views
7

Czy istnieje idiom języka Ruby dla popping elementów z tablicy, gdy warunek jest prawdziwy, i zwracanie kolekcji?Czy istnieje idiom ruby ​​do wstawiania elementów z tablicy, gdy warunek jest prawdziwy

tj,

# Would pop all negative numbers from the end of 'array' and place them into 'result'. 
result = array.pop {|i| i < 0} 

Z tego co mogę powiedzieć, coś jak wyżej nie istnieje.

obecnie używam

result = [] 
while array.last < 0 do 
    result << array.pop 
end 
+0

bardziej ogólny; pop wszystkie pasujące elementy z końca tablicy. Jeśli napotkasz niespójny element, zatrzymaj się. –

+1

"Nie pomijaj niezgodności": Mam problem z analizą tego. –

+0

Przeformułowałem go –

Odpowiedz

7

Może szukasz take_while?

array = [-1, -2, 0, 34, 42, -8, -4] 
result = array.reverse.take_while { |x| x < 0 } 

result byłoby [-8, -4].

Aby uzyskać oryginalny wynik, można zamiast tego użyć drop_while.

result = array.reverse.drop_while { |x| x < 0 }.reverse 

result byłoby [-1, -2, 0, 34, 42] w tym przypadku.

+0

Czy istnieje wariant take_while, który usuwa również elementy z tablicy? –

+0

@ComputerLinguist Nie sądzę, niestety. Rozejrzałem się po dokumentach i niczego nie znalazłem. – squiguy

+2

@ComputerLinguist, używając 'drop_while' w tym samym kontekście powyżej zwróci oryginalną tablicę z usuniętymi elementami. TO ZNACZY. 'result = [-1, -2, 0, 34, 42]' – AGS

1

Można go napisać samemu:

class Array 
    def pop_while(&block) 
    result = [] 
    while not self.empty? and yield(self.last) 
     result << self.pop 
    end 
    return result 
    end 
end 

result = array.pop_while { |i| i < 0 } 
+0

To prawda, ale naprawdę szukam czegoś bardziej standardowego/idomatic –

+2

Istnieją metody 'take_while' i' drop_while', więc 'pop_while' wygląda tak jak ... Obawiam się, że nie ma czegoś takiego jak to w standardzie rubinowym. – Huluk

0

W przypadku szukasz rozwiązania pop wszystkie elementy, które spełniają warunek, należy rozważyć select po którym następuje delete_if, np

x = [*-10..10].sample(10) 
# [-9, -2, -8, 0, 7, 9, -1, 10, -10, 3] 
neg = x.select {|i| i < 0} 
# [-9, -2, -8, -1, -10] 
pos = x.delete_if {|i| i < 0} 
# [0, 7, 9, 10, 3] 
# note that `delete_if` modifies x 
# so at this point `pos == x` 
Powiązane problemy