# Running multiple closures per iteration

**URL:** <https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200>\
**Category:** Ruby\
**Created:** [August 3, 2007, 7:38pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200 "2007-08-03T19:38:52Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![syncopated](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/85f322/32.png) [@syncopated](https://www.ruby-forum.com/u/syncopated)\
**Post date:** [August 3, 2007, 7:38pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200/1 "2007-08-03T19:38:52Z")

</div>

Is there a way to run more than one closure per iteration through a  
collection? For example, if I want to do the following two things, can  
I combine them so that I only end up with one pass over the collection,  
without doing a manual for loop?

o = a.select {|x| x \>= 0}  
p = a.inject(0) {|s, x| s += x}

Such a combination is useful when iterating through a collection is  
expensive, e.g. on a large file on a slow disk.

---

<div class="post-metadata">

**Author:** ![syncopated](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/85f322/32.png) [@syncopated](https://www.ruby-forum.com/u/syncopated)\
**Post date:** [August 3, 2007, 7:53pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200/2 "2007-08-03T19:53:42Z")

</div>

Joshua C. wrote:

> Is there a way to run more than one closure per iteration through a  
> collection? For example, if I want to do the following two things, can  
> I combine them so that I only end up with one pass over the collection,  
> without doing a manual for loop?
> 
> o = a.select {|x| x \>= 0}  
> p = a.inject(0) {|s, x| s += x}
> 
> Such a combination is useful when iterating through a collection is  
> expensive, e.g. on a large file on a slow disk.

Did you mean

o = a.select {|x| x \>= 0}  
p = o.inject(0) {|s, x| s += x}  
^^^  
?

Then you can do this:

a = [1,-1,2,-2,3,-3]  
sp = a.inject(0) {|s, x| x \>= 0 ? s + x : s}  
p sp # ==\> 6

(note that += is not needed, + is good enough)

But there is no way in general to combine two iterations.

---

<div class="post-metadata">

**Author:** ![syncopated](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/85f322/32.png) [@syncopated](https://www.ruby-forum.com/u/syncopated)\
**Post date:** [August 3, 2007, 8:19pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200/3 "2007-08-03T20:19:40Z")

</div>

Joel VanderWerf wrote:

> Did you mean
> 
> o = a.select {|x| x \>= 0}  
> p = o.inject(0) {|s, x| s += x}  
> ^^^  
> ?

No, I meant to compute two different things from a.

---

<div class="post-metadata">

**Author:** ![syncopated](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/85f322/32.png) [@syncopated](https://www.ruby-forum.com/u/syncopated)\
**Post date:** [August 3, 2007, 8:34pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200/4 "2007-08-03T20:34:49Z")

</div>

On 8/3/07, Joshua C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Joel VanderWerf wrote:
> 
> > Did you mean
> > 
> > o = a.select {|x| x \>= 0}  
> > p = o.inject(0) {|s, x| s += x}  
> > ^^^  
> > ?
> 
> No, I meant to compute two different things from a.

Well, it’s not pretty, but here’s my best shot at it

o, p = a.inject( [[], 0] ) do |ary,x|  
ary[0] \<\< x if x \>= 0  
ary[1] += x  
ary  
end

I don’t think Ruby natively supports such a creature, though. Please  
correct me if I’m wrong.

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![syncopated](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/85f322/32.png) [@syncopated](https://www.ruby-forum.com/u/syncopated)\
**Post date:** [August 3, 2007, 10:54pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200/5 "2007-08-03T22:54:08Z")

</div>

Hi –

On Sat, 4 Aug 2007, Stefano C. wrote:

> a.inject(0) {|s, x| s + x}  
> =\> 6
> 
> > Such a combination is useful when iterating through a collection is  
> > expensive, e.g. on a large file on a slow disk.
> 
> o = 0; p = []  
> a.each { |x| o \<\< x if x \>= 0; p += x }  
> a.each { |x| p \<\< x if x \>= 0; o += x }

🙂

David

---

<div class="post-metadata">

**Author:** ![syncopated](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/85f322/32.png) [@syncopated](https://www.ruby-forum.com/u/syncopated)\
**Post date:** [August 3, 2007, 10:51pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200/6 "2007-08-03T22:51:06Z")

</div>

On Aug 3, 7:38 pm, Joshua C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Is there a way to run more than one closure per iteration through a  
> collection? For example, if I want to do the following two things, can  
> I combine them so that I only end up with one pass over the collection,  
> without doing a manual for loop?
> 
> o = a.select {|x| x \>= 0}  
> p = a.inject(0) {|s, x| s += x}

btw, you don’t need the += operator here:  
a.inject(0) {|s, x| s + x}  
=\> 6

> Such a combination is useful when iterating through a collection is  
> expensive, e.g. on a large file on a slow disk.

o = 0; p = []  
a.each { |x| o \<\< x if x \>= 0; p += x }

---

<div class="post-metadata">

**Author:** ![syncopated](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/85f322/32.png) [@syncopated](https://www.ruby-forum.com/u/syncopated)\
**Post date:** [August 4, 2007, 1:21pm UTC](https://www.ruby-forum.com/t/running-multiple-closures-per-iteration/111200/7 "2007-08-04T13:21:15Z")

</div>

Tim P. schrieb:

> Well, it’s not pretty, but here’s my best shot at it
> 
> o, p = a.inject( [[], 0] ) do |ary,x|  
> ary[0] \<\< x if x \>= 0  
> ary[1] += x  
> ary  
> end

you can beautify this to

o, p = a.inject( [[], 0] ) do |(l, s), x|  
[x \>= 0 ? l \<\< x : l, s + x]  
end

> I don’t think Ruby natively supports such a creature, though. Please  
> correct me if I’m wrong.

Well, depends on what ‘natively’ realy means…

> Blessings,  
> TwP

cheers

Simon
