Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Ruby (http://www.velocityreviews.com/forums/f66-ruby.html)
-   -   Running multiple closures per iteration (http://www.velocityreviews.com/forums/t842999-running-multiple-closures-per-iteration.html)

Joshua Chia 08-03-2007 05:38 PM

Running multiple closures per iteration
 
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.
--
Posted via http://www.ruby-forum.com/.


Joel VanderWerf 08-03-2007 05:52 PM

Re: Running multiple closures per iteration
 
Joshua Chia 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.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407


Joshua Chia 08-03-2007 06:19 PM

Re: Running multiple closures per iteration
 
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.
--
Posted via http://www.ruby-forum.com/.


Tim Pease 08-03-2007 06:33 PM

Re: Running multiple closures per iteration
 
On 8/3/07, Joshua Chia <joshchia@gmail.com> 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


Stefano Cobianchi 08-03-2007 08:46 PM

Re: Running multiple closures per iteration
 
On Aug 3, 7:38 pm, Joshua Chia <joshc...@gmail.com> 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 }

--
S.


dblack@rubypal.com 08-03-2007 08:52 PM

Re: Running multiple closures per iteration
 
Hi --

On Sat, 4 Aug 2007, Stefano Cobianchi wrote:

> On Aug 3, 7:38 pm, Joshua Chia <joshc...@gmail.com> 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 }

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

:-)


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)


Simon Kröger 08-04-2007 11:16 AM

Re: Running multiple closures per iteration
 
Tim Pease schrieb:
> On 8/3/07, Joshua Chia <joshchia@gmail.com> 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


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


All times are GMT. The time now is 10:32 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.