Count array keys possible?

Hi,

newbie question(i guess)

a = Bookings.find(:all, :conditions => [3.days.ago])
a = [id : 1, departure : ‘AMS’, arrival => ‘NY’],[id : 2, departure :
‘AMS’, arrival => ‘BCN’],[id : 3, departure : ‘AMS’, arrival =>
‘BKK’],[id : 4, departure : ‘AMS’, arrival => ‘BKK’] ect.

The value of the key departure and arrival is dynamic based on
table(3000 combinations) and the bookings

I want to find the bookings and count the arrival and departure(s). I
the case of the code above, i want the following output.

departure = AMS > total = 5
arrival = BCN > total = 1
arrival = NY > total = 1
arrival = BKK > total = 2

How can i do this

Grtz…remco

departures = [ ‘AMS’, ‘BCN’, ‘BBK’ ]
sums = {}
departures.each do |d|
sums[d] ||= 0
sums[d] = sums[d] + 1
end
puts( sums )

Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Tue, Feb 24, 2009 at 2:57 PM, Remco S.

Maurício Linhares wrote:

departures = [ ‘AMS’, ‘BCN’, ‘BBK’ ]
sums = {}
departures.each do |d|
sums[d] ||= 0
sums[d] = sums[d] + 1
end
puts( sums )

Maur�cio Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Tue, Feb 24, 2009 at 2:57 PM, Remco S.

Hi Maurício,

Thanks for your reply.

I have more bookings from the same departures, like this:

departures = [ ‘AMS’, ‘BCN’, ‘BKK’, ‘AMS’, ‘AMS’, ‘BKK’]

Then i want to count the departures, like this based on the array above:

AMS => ‘3’
BCN => ‘1’
BKK => ‘2’

Is this possibly?

(the objective is to store the values in a graph for management-info)

Thanks in advance…

remco

Maurício Linhares wrote:

Why don’t you do it at the database with an order by?

Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Wed, Feb 25, 2009 at 1:04 PM, Remco S.

hmm…i don’t now how to count the values through the order_by condition
(yep…i am newbie)

grtz…remco

Why don’t you do it at the database with an order by?

Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Wed, Feb 25, 2009 at 1:04 PM, Remco S.

Ok, so this is the best time to start learning SQL, here’s a good
start → Head First SQL [Book]

Here’s how the query would look like:

SELECT departure, COUNT(*) AS departures_count FROM bookings GROUP BY
departure

Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Wed, Feb 25, 2009 at 1:32 PM, Remco S.

On Feb 25, 2009, at 11:37 AM, Maurício Linhares wrote:

http://alinhavado.wordpress.com/ (pt-br) | http://
blog.codevader.com/ (en)

You can do some of this with ActiveRecord, too. (Note this is my own
little extension so don’t go looking in ActiveRecord documentation for
this particular module.)

module ActiveRecord
module Groups
def groups(columns)
return if columns.empty?
options = columns.last.is_a?(Hash) ? columns.pop.dup : {}
select = columns.join(‘,’) + ',count(
) AS count_all’
group = columns.join(‘,’)
columns = (columns + [‘count_all’]).map{|c|c.to_s}
find(:all, :select => select, :conditions =>
options.delete(:conditions),
:group => group).map {|rec| rec.attributes(:only =>
columns).values_at(*columns) }
end
end
end

require ‘pp’

pp Booking.count # so the Booking model class will exist
class Booking
extend ActiveRecord::Groups
end

cols = [ :departure ]
result = Booking.groups(*cols)

which gives something like

#=> [ [“AMS”, 3 ], [“BCN”, 1], [“BKK”, 2] ]

or write that out to a CSV file

require ‘fastercsv’
filename = ‘counts.csv’
FasterCSV.open(filename, ‘w’) do |csv|
csv << cols
result.each {|r| csv << r }
end
puts “%5d rows in %s”%[result.size, filename]

Exercises for the reader (the OP, in particular):

  • look at how the :select option can limit the attributes created in
    the model
  • read how the :group option works on ActiveRecord::Base.find
  • look at the #attributes method of a model and the Hash#values_at
    method

-Rob

Rob B. http://agileconsultingllc.com
[email protected]