Został on zapytał:
chcę złapać pierwsze 10 sztuk następnie pozostawić „każdego” pętlę.
Zastosowanie throw
i catch
do osiągnięcia tego celu, z nielicznymi zmianami w przykładzie:
catch(:done) do
c = 0
collected = []
items.each do |item|
collected << item
throw(:done, collected) if c == 9 # started at 0
c += 1
end
collected # if the list is less than 10 long, return what was collected
end
Wystarczy throw
etykieta :done
z collected
i catch
który czeka na :done
powróci collected
.
I „Ruby” to się trochę:
catch(:done) do
items.inject([]) do |collected, item|
throw(:done, collected) if collected.size == 10
collected << item # collected gets returned here and populates the first argument of this block
end
end
nie wiem dlaczego niektórzy ludzie nie chcą używać inject
i używać reduce
zamiast (są równoważne), gdy wyraźnie pusta tablica podane do inject([])
jest wstrzyknięto item
s! W każdym razie inject
zwróci collected
, jeśli jest mniej niż 10 elementów.
Większość odpowiedzi próbuje odpowiedzieć na pytanie, jaka może być intencja pytania, a nie pytanie, a items.take(10)
ma w tym przypadku sens. Ale mogę sobie wyobrazić, że chcę pobrać pierwsze przedmioty, które pasują do mojego budżetu na 100 dolarów. Następnie można po prostu:
catch(:done) do
items.inject({items: [], budget: 100}) do |ledger, item|
remainder = ledger[:budget] - item.price
if remainder < 0
throw(:done, ledger)
else
ledger.tap do |this|
this[:items] << item
this[:budget] = remainder
end # tap just returns what is being tapped into, in this case, ledger
end
end
end
sugeruję odpowiedź nimrodm, że używa się: http://stackoverflow.com/questions/1568288/escaping-the-each-iteration-early-in-ruby/1568445#1568445 –