Is there no method for an array that will tell me the # of occurrences

for an item?

IE: ["a", "a", "a", "b", "c", "c"].count("a") #producing 3 ?

I almost thought that rindex would do the trick when looking at the

class docs but.. the example was just engineered to trick me :-(

I realize I could pass these to a block and count but.. wanted to make

sure it didn't exist. If not, why? Thank you.. ( I did search btw.. no

avail )

Also, what's the best way of printing out each unique item and the

number of times it occurs, sorted by numerically by the number of

times it occurs?

IE: in my example above, i'd like to see (sorted by occurrence

greatest to least)

#desired output:

a: 3

c: 2

b: 1

Or sorted from least to greatest:

#desired output:

b: 1

c: 2

a: 3

I was able to hack it by using a hash doing various things to it.. but

it didn't seem "rubyish".

Thank you for any input.

What could be more ruby-ish than monkeypatching a built-in class and

using inject in the process?

class Array

def counts

inject( Hash.new(0) ){ |hash,element|

hash[ element ] +=1

hash

}

end

def counts_up

counts.sort_by{ |k,v| v }

end

def counts_down

counts.sort_by{ |k,v| -v }

end

end

a = ["a", "a", "a", "b", "c", "c"]

p a.counts, a.counts_up, a.counts_down

#=> {"a"=>3, "b"=>1, "c"=>2}

#=> [["b", 1], ["c", 2], ["a", 3]]

#=> [["a", 3], ["c", 2], ["b", 1]]

array.select { |i| i == 'a' }.length

or array.inject(0) { |count, item| count += 1 if item == 'a'; count }

As you say:

puts array.inject(Hash.new(0)) { |hash, item| hash[item] += 1

hash }.sort_by { |k, v| v }.map { |k, v| "#{k}:#{v}" }

Hi,

At Thu, 12 Oct 2006 11:52:19 +0900,

x1 wrote in [ruby-talk:219218]:

FYI, Enumerable in 1.9 has that method.

--

Nobu Nakada

At Thu, 12 Oct 2006 11:52:19 +0900,

x1 wrote in [ruby-talk:219218]:

FYI, Enumerable in 1.9 has that method.

--

Nobu Nakada

Wow Capaldo, that worked! I fear for the next java programmer who has

to make sense of my code when I leave ;-)

To reverse sort, I added .reverse.. Here's the final product:

puts ["a", "a", "a", "b", "c", "c"].inject(Hash.new(0)) { |hash, item|

hash[item] += 1

hash }.sort_by { |k, v| v }.reverse.map { |k, v| "#{k}:#{v}" }

Thanks so much.

Nakada, I look forward to using it in 1.9 :-)

to make sense of my code when I leave ;-)

To reverse sort, I added .reverse.. Here's the final product:

puts ["a", "a", "a", "b", "c", "c"].inject(Hash.new(0)) { |hash, item|

hash[item] += 1

hash }.sort_by { |k, v| v }.reverse.map { |k, v| "#{k}:#{v}" }

Thanks so much.

Nakada, I look forward to using it in 1.9 :-)

and.. so you're aware.. my hacky code was something like this:

items = {}

["a", "a", "a", "b", "c", "c"].each do |i|

if items.include? i

items[i] += 1

else

items[i] = 1

end

end

items.sort {|a,b| a[1]<=>b[1]}.reverse.each do |a, b|

puts a + ":" + b.to_s

end

horrific eh?

items = {}

["a", "a", "a", "b", "c", "c"].each do |i|

if items.include? i

items[i] += 1

else

items[i] = 1

end

end

items.sort {|a,b| a[1]<=>b[1]}.reverse.each do |a, b|

puts a + ":" + b.to_s

end

horrific eh?

items = Hash.new(0)

["a","a","a","b","c","c"].each do |i|

items[i] += 1

end

items.sort_by {|key,value| -value}.each do |key, value|

puts "#{a}:#{b}"

end

Slightly less horrific?

["a","a","a","b","c","c"].each do |i|

items[i] += 1

end

items.sort_by {|key,value| -value}.each do |key, value|

puts "#{a}:#{b}"

end

Slightly less horrific?

Hi,

You can use ["a", "a", "a", "b", "c", "c"].grep("a").size

array.uniq.sort_by{|x|array.grep(x).size}.reverse.each{|x|puts "#{x}:

#{array.grep(x).size}"}

array.uniq.sort_by{|x|array.grep(x).size}.each{|x|puts "#{x}:

#{array.grep(x).size}"}

Regards,

Park Heesob

Ah ok.. I'm with ya. Meet "sort_by", my new friend. Thanks again :-D

Smalltalk has a collection class called Bag, which is an unordered

collection of objects which keeps track of the number of occurences of

each equal element in the collection, so you can do something like:

bag <- Bag.new

bag.add: 1;add: 2: add: 1; add: 4

bag.occurencesOf: 1 => 2

bag.occurencesOf: 1 => 1

bag.remove: 1

bag.occurrencesOf: 1 => 1

Now Bag is kind of the black sheep of the Smalltalk collection

classes. Most Smalltalkers would either never use it or overuse it.

The only use I could think of was to implement a histogram.

--

Rick DeNatale

My blog on Ruby

http://www.yqcomputer.com/

1. IFFT of custom frequency array - confusion with the time domain sampling frequency

2. Creating swept frequency using array values as time values tia sal22

3. swept frequency using array values as time values tia sal22

4. Formula for counting frequency then sorting

5. Counting the frequency of data in an array

6. frequency count or number of occurences of a number in an array

7. how to generate an associative array and count frequency?

8. Count frequencies; Pareto of nonumeric values

9. count frequency of two values in same row

10. How to count frequency of a series of values within certain ranges

11. Counting the frequency of multiple values within a column

12. Find and Count Frequency of Numeric Value in Non-Contiguous Rows

13. Counting unique values + frequency

14. Counting frequency of value in a range

15. Frequency spectrum with fft of a real valued array...?

10 post • Page:**1** of **1**