|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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? |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
# soprano:
# How about just listA = [["A",30], ["B",20], ["C",10], ["D",20]] # Or listH = { "A"=>30, "B"=>20, "C"=>10, "D"=>20 } # Then sort the list listSA = listA.sort{|a,b| ret = b[1]<=>a[1]; (ret==0)? a[0]<=>b[0]: ret} # Works also with listH listSH = listH.sort{|a,b| ret = b[1]<=>a[1]; (ret==0)? a[0]<=>b[0]: ret} On Mon, 7 Jan 2008 02:30:13 +0900, "soprano" <spicyjalapeno@gmail.com> said: > Is it possible to add rankings to an array (allowing ties):.... |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Yes, I see how to sort an array, but that will produce (unless I am
mistaken): [ [1, { :name => "A", :points => 30 }], [2, { :name => "B", :points => 20 }], [3, { :name => "D", :points => 20 }], [4, { :name => "C", :points => 10 }] ] and I want to account for ties (in points). |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Great, thanks!
On Jan 6, 11:15=A0am, Robert Klemme <shortcut...@googlemail.com> wrote: > Preparation: > > data =3D [ > =A0 =A0{ :name =3D> "A", :points =3D> 30 }, > =A0 =A0{ :name =3D> "B", :points =3D> 20 }, > =A0 =A0{ :name =3D> "C", :points =3D> 10 }, > =A0 =A0{ :name =3D> "D", :points =3D> 20 } > ] > > Here's one way: > > sorted =3D data.sort_by {|x| -x[:points]} > ranked =3D sorted.inject([0,1,nil,[]]) do |(rk, cn, lst, arr), x| > =A0 =A0tmp_lst =3D x[:points] > > =A0 =A0if tmp_lst =3D=3D lst > =A0 =A0 =A0cn +=3D 1 > =A0 =A0else > =A0 =A0 =A0rk +=3D cn > =A0 =A0 =A0cn =A0=3D 1 > =A0 =A0end > > =A0 =A0[rk, cn, tmp_lst, arr << [rk, x]] > end.last > > And here's another: > > hashed =3D data.inject(Hash.new {|h,k| h[k] =3D []}) do |ha, x| > =A0 =A0ha[x[:points]] << x > =A0 =A0ha > end > sorted =3D hashed.sort_by {|k,v| -k} > ranked =3D sorted.inject([]) do |arr, (k,v)| > =A0 =A0rk =3D arr.size + 1 > =A0 =A0v.each {|x, idx| arr << [rk, x]} > =A0 =A0arr > end > > Have fun! |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Sun, 06 Jan 2008 13:11:02 -0500, soprano wrote:
> Yes, I see how to sort an array, but that will produce (unless I am > mistaken): > > [ > [1, { :name => "A", :points => 30 }], [2, { :name => "B", :points => > 20 }], [3, { :name => "D", :points => 20 }], [4, { :name => "C", > :points => 10 }] > ] > > and I want to account for ties (in points). Assuming you have the array above after sorting, make a pass across it as follows: a.times do |n| a[n][0]=a[n-1][0] if a[n][1][:points]==a[n-1][1][:points] end -- Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory. Department of Computer Science. Illinois Institute of Technology. http://www.iit.edu/~kbloom1/ |
|
![]() |
| Outils de la discussion | |
|
|