# Contionnal sum

**URL:** <https://www.ruby-forum.com/t/contionnal-sum/137724>\
**Category:** Ruby\
**Created:** [May 15, 2008, 6:26pm UTC](https://www.ruby-forum.com/t/contionnal-sum/137724 "2008-05-15T18:26:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [May 15, 2008, 6:26pm UTC](https://www.ruby-forum.com/t/contionnal-sum/137724/1 "2008-05-15T18:26:22Z")

</div>

Hi,

I am wondering if it is possible to create a conditionnal sum.

For instance I would like to do something like this:

@total\_amount = @orders.sum { |order| order.amount if order.paid == true  
}

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [May 15, 2008, 6:44pm UTC](https://www.ruby-forum.com/t/contionnal-sum/137724/2 "2008-05-15T18:44:15Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Fernando P. wrote:  
| Hi,  
|  
| I am wondering if it is possible to create a conditionnal sum.  
|  
| For instance I would like to do something like this:  
|  
| @total\_amount = @orders.sum { |order| order.amount if order.paid == true  
| }

Should be.

Something like this (untested, and unsafe, probably not even correct):

def conditional\_sum order, condition  
~ order.each do |o|  
~ sum = sum + o unless o.paid?  
~ end  
~ return sum  
end

I made the idea explicit, so that you should at least get the idea.

* * *

Phillip G.  
Twitter: [twitter.com/cynicalryan](http://twitter.com/cynicalryan)  
Blog: [http://justarubyist.blogspot.com](http://justarubyist.blogspot.com)

You! What PLANET is this!  
~ – McCoy, “The City on the Edge of Forever”, stardate 3134.0  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.8 (MingW32)  
Comment: Using GnuPG with Mozilla - [http://enigmail.mozdev.org](http://enigmail.mozdev.org)

iEYEARECAAYFAkgsZ9UACgkQbtAgaoJTgL8L2gCeLZyAQcn6+o+4McD7qQLJlL1o  
qEUAn0JrnuPs7XVBNUYAEuCd6gUIsjBO  
=k8YY  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [May 15, 2008, 6:48pm UTC](https://www.ruby-forum.com/t/contionnal-sum/137724/3 "2008-05-15T18:48:23Z")

</div>

On Thu, May 15, 2008 at 6:26 PM, Fernando P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> I am wondering if it is possible to create a conditionnal sum.
> 
> For instance I would like to do something like this:
> 
> @total\_amount = @orders.sum { |order| order.amount if order.paid == true  
> }

sum… is that Rails? If that’s the case you could filter them before:

# untested

@total\_sum = @orders.select(&:paid).sum(&:amount)

Although AR has another SQL-based #sum that may be worth exploring if  
@orders are ARs.

That being said, perhaps you weren’t aware of the fact that  
Enumerable#sum is defined by Active Support, but let me point out that  
those extensions are discussed in the very Rails mailing list.

– fxn

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [May 15, 2008, 7:36pm UTC](https://www.ruby-forum.com/t/contionnal-sum/137724/4 "2008-05-15T19:36:06Z")

</div>

- Fernando P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (18:26) schrieb:

> Hi,
> 
> I am wondering if it is possible to create a conditionnal sum.
> 
> For instance I would like to do something like this:
> 
> @total\_amount = @orders.sum { |order| order.amount if order.paid == true  
> }

@total\_amount = @orders.inject(0) do | sum, order |  
order.paid ? sum + order.amount : sum  
end

or

@total\_amount = @orders.select { | o | o.paid }. sum

BTW: Comparing a boolean value to true or false only shows you don’t  
understand booleans.

And if that order class is yours: I’d rather call the accessor »paid?«.

mfg, simon … l

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [May 15, 2008, 7:40pm UTC](https://www.ruby-forum.com/t/contionnal-sum/137724/5 "2008-05-15T19:40:47Z")

</div>

Xavier N. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> # untested
> 
> @total\_sum = @orders.select(&:paid).sum(&:amount)
> 
> Although AR has another SQL-based #sum that may be worth exploring if  
> @orders are ARs.
> 
> That being said, perhaps you weren’t aware of the fact that  
> Enumerable#sum is defined by Active Support, but let me point out that  
> those extensions are discussed in the very Rails mailing list.

Enumerable#sum is also in facets.  
The .select method is a good way, but you can use less memory by doing

@orders.sum {|order| order.paid? order.amount : 0 }

Facets’ #sum doesn’t skip nils, so the method you proposed won’t work.

–Ken

---

<div class="post-metadata">

**Author:** ![fipa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9e8a1a/32.png) [@fipa](https://www.ruby-forum.com/u/fipa)\
**Post date:** [May 15, 2008, 9:46pm UTC](https://www.ruby-forum.com/t/contionnal-sum/137724/6 "2008-05-15T21:46:47Z")

</div>

Thank you all for your messages. Yes it is a piece of code I am using in  
a Rails app. I thought it would fit better in this list rather than the  
Rails one, as the problem is not specific to Rails.

> BTW: Comparing a boolean value to true or false only shows you don’t  
> understand booleans.

Yeah I knew someone would nail me on this. I wanted to make my problem  
clear, so that’s why I specified this silly “== true”. In my real code,  
I don’t have it trust me. If I hadn’t put it, someone would have come up  
with “hey wtf is that order.paid thing!?”

> The .select method is a good way, but you can use less memory by doing
> 
> @orders.sum {|order| order.paid? order.amount : 0 }

This is fantastic, I knew the solution was super simple. Day after day I  
love Ruby more and more.

Best regards, and once again thank you very much for assisting me.
