Ruby Code Snippet: Array.count

Maybe this functionality is already somewhere in Ruby, but I could not
find it. This little snippet extends Array with a count method. It takes
a code block that can be used to count elements that match a specific
condition:

a = Array[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
puts a.count { |v| v < 5 }

==> 4

The code:

class Array
def count(&action)
count = 0
self.each { |v| count = count + 1 if action.call(v) }
return count
end
end

Ruby is sweet :slight_smile:

S.

¡¡¡

–
stefan.arentz@soze.com / http://www.soze.com/stefan
"Think of Your cellular phone as a party line", Ian Goldberg

This is already available with Enumerable#find_all:

a = (1…10).to_a
puts a.find_all {|v| v < 5 }.size

4

Ian

¡¡¡

On Sat 05 Jul 2003 at 08:01:38 +0900, Stefan Arentz wrote:

Maybe this functionality is already somewhere in Ruby, but I could not
find it. This little snippet extends Array with a count method. It takes
a code block that can be used to count elements that match a specific
condition:

a = Array[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
puts a.count { |v| v < 5 }

–
Ian Macdonald | Crazee Edeee, his prices are INSANE!!!
System Administrator |
ian@caliban.org |
http://www.caliban.org |
>

Stefan Arentz wrote:

Maybe this functionality is already somewhere in Ruby, but I could not
find it. This little snippet extends Array with a count method. It takes
a code block that can be used to count elements that match a specific
condition:

a = Array[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
puts a.count { |v| v < 5 }

==> 4

The code:

class Array
def count(&action)
count = 0
self.each { |v| count = count + 1 if action.call(v) }
return count
end
end

I’m starting to like using ‘inject’ for this kind of thing, but it isn’t
as clear to read:

class Array
def count
inject(0) {|sum, e| yield(e) ? sum + 1 : sum }
end
end

Ruby is sweet :slight_smile:

Agreed :slight_smile:

Cheers

Dave

Ian Macdonald ian@caliban.org writes:

¡¡¡

On Sat 05 Jul 2003 at 08:01:38 +0900, Stefan Arentz wrote:

Maybe this functionality is already somewhere in Ruby, but I could not
find it. This little snippet extends Array with a count method. It takes
a code block that can be used to count elements that match a specific
condition:

a = Array[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
puts a.count { |v| v < 5 }

This is already available with Enumerable#find_all:

a = (1…10).to_a
puts a.find_all {|v| v < 5 }.size

4

Yes but this is very inefficient if you have large collections. My version
does not need to create a new temporary collection just to count it.

S.

I have added your Array#count (using inject), here:

¡¡¡

On Sat, 05 Jul 2003 14:20:35 +0900, Dave Thomas wrote:

class Array
def count
inject(0) {|sum, e| yield(e) ? sum + 1 : sum }
end
end

–
Simon Strandgaard

Stefan Arentz wrote:
I’m starting to like using ‘inject’ for this kind of thing, but it isn’t
as clear to read:

class Array
def count
inject(0) {|sum, e| yield(e) ? sum + 1 : sum }
end
end

Injects are never clear to read, are they?

Ruby is sweet :slight_smile:
Agreed :slight_smile:

ACK.

Cheers,

¡¡¡

In article 3F065223.2030809@pragprog.com, Dave Thomas wrote:

–
Volker Grabsch
—<<(())>>—
\frac{\left|\vartheta_0\times{\ell,\kappa\in\Re}\right|}{\sqrt
[G]{-\Gamma(\alpha)\cdot\mathcal{B}^{\left[\oint!c_\hbar\right]}}}

The other version is faster IMHO, and in this case at least as readable:

class Array
def count
sum = 0
each { |x| sum += 1 if yield x }
sum
end
end

¡¡¡

On Sat, Jul 05, 2003 at 03:43:00PM +0900, Simon Strandgaard wrote:

On Sat, 05 Jul 2003 14:20:35 +0900, Dave Thomas wrote:

class Array
def count
inject(0) {|sum, e| yield(e) ? sum + 1 : sum }
end
end

I have added your Array#count (using inject), here:

http://www.rubygarden.org/ruby?StandardClassExtensions/Array

–
_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

‘Ooohh… “FreeBSD is faster over loopback, when compared to Linux
over the wire”. Film at 11.’
– Linus Torvalds

Simon Strandgaard wrote:

¡¡¡

On Sat, 05 Jul 2003 14:20:35 +0900, Dave Thomas wrote:

class Array
def count
inject(0) {|sum, e| yield(e) ? sum + 1 : sum }
end
end

I have added your Array#count (using inject), here:

My code was written in response to the OP’s. However, if you’re going to
save it for posterity, you should really put it under Enumerable.

Dave

In article be61dp$j6g$03$1@news.t-online.com,

¡¡¡

Volker Grabsch volker_grabsch@v.notjusthosting.com wrote:

Injects are never clear to read, are they?

Once you assimilate the idiom they aren’t too bad. Readability only
“happens” when a reader looks at something, I don’t think it’s an
inherent property of the material being read.

Mike

–
mike@stok.co.uk | The “`Stok’ disclaimers” apply.
http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA
mike@exegenix.com | Fingerprint 0570 71CD 6790 7C28 3D60
http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA

Ok… I have now added both :slight_smile:

¡¡¡

On Sat, 05 Jul 2003 16:48:07 +0900, Mauricio FernĂĄndez wrote:

On Sat, Jul 05, 2003 at 03:43:00PM +0900, Simon Strandgaard wrote:

I have added your Array#count (using inject), here:

http://www.rubygarden.org/ruby?StandardClassExtensions/Array

The other version is faster IMHO, and in this case at least as readable:

class Array
def count
sum = 0
each { |x| sum += 1 if yield x }
sum
end
end

–
Simon Strandgaard

Mauricio FernĂĄndez wrote:

The other version is faster IMHO, and in this case at least as readable:

Agreed (in fact I believe I said the original version was more
readable). I just wanted to post an alternative to start introducing
#inject…

Cheers

Dave