Se preguntó:
Quiero agarrar los primeros 10 elementos entonces salen de la "cada" bucle.
Uso throw
y catch
para lograr esto, con pocos cambios en el ejemplo:
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
Simplemente throw
la etiqueta :done
con collected
y la catch
que está a la espera de :done
volverá collected
.
Y para "Ruby" esto un poco:
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
No sé por qué algunas personas se niegan a usar inject
y utilizar reduce
lugar (que son equivalentes) cuando claramente la matriz vacía dado a inject([])
es siendo inyectado con item
s! De todos modos, el inject
devolverá collected
si hay menos de 10 elementos.
La mayoría de las respuestas intentan responder cuál podría ser el objetivo de la pregunta en lugar de lo que se solicitó y items.take(10)
tiene perfecto sentido en ese caso. Pero me imagino que quiero tomar los primeros artículos que encajan dentro de mi presupuesto de $ 100. A continuación, puede:
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
Sugiero respuesta de nimrodm que utiliza tomar: http://stackoverflow.com/questions/1568288/escaping-the-each-iteration-early-in-ruby/1568445#1568445 –