I have found myself needing to sort a hash collection often, by a value within the hashes. The last instance where I needed this was to sort an aggregated result set of multiple union queries. So sorting with an order by clause would not work across the unions.
The solution is below. I pass a sortclause into the method that would look like this companyname asc or company_name desc.
def stats(sort_clause)
# queries, etc.
...
find_by_sql(sql).each do |acct|
aid = acct.id.to_i
results[aid] = {} unless results[aid]
month = acct.monthname
case (month)
when 'last'
results[aid][:spend_last] = acct.spend.to_f
when 'this'
results[aid][:spend_this] = acct.spend.to_f
when 'total'
results[aid][:company_name] = acct.company_name
results[aid][:balance] = acct.bal.to_f
results[aid][:campaigns] = acct.campaign_count.to_i
results[aid][:keywords] = acct.keyword_count.to_i
end
end
sort_col, order = sort_clause.split(' ')
logger.debug("sort_clause: #{sort_clause}")
results = results.sort_by{ |item|
item[1][sort_col.intern]
}
if (order =~ /desc/i)
results.reverse!
end
results
end
