Robert Klemme
1/6/2008 6:13:00 PM
On 06.01.2008 18:30, soprano wrote:
> Is it possible to add rankings to an array (allowing ties):
>
> Example (rate on points field) - convert
>
> [
> { :name => "A", :points => 30 },
> { :name => "B", :points => 20 },
> { :name => "C", :points => 10 },
> { :name => "D", :points => 20 }
> ]
>
> to
>
> [
> [1, { :name => "A", :points => 30 }],
> [2, { :name => "B", :points => 20 }],
> [2, { :name => "D", :points => 20 }],
> [4, { :name => "C", :points => 10 }]
> ]
>
> How to do this in Ruby?
Preparation:
data = [
{ :name => "A", :points => 30 },
{ :name => "B", :points => 20 },
{ :name => "C", :points => 10 },
{ :name => "D", :points => 20 }
]
Here's one way:
sorted = data.sort_by {|x| -x[:points]}
ranked = sorted.inject([0,1,nil,[]]) do |(rk, cn, lst, arr), x|
tmp_lst = x[:points]
if tmp_lst == lst
cn += 1
else
rk += cn
cn = 1
end
[rk, cn, tmp_lst, arr << [rk, x]]
end.last
And here's another:
hashed = data.inject(Hash.new {|h,k| h[k] = []}) do |ha, x|
ha[x[:points]] << x
ha
end
sorted = hashed.sort_by {|k,v| -k}
ranked = sorted.inject([]) do |arr, (k,v)|
rk = arr.size + 1
v.each {|x, idx| arr << [rk, x]}
arr
end
Have fun!
Kind regards
robert