ekharrtoll
ekharrtoll

Reputation: 15

Ruby: Sorting 2 arrays using values from one of them

I'm creating a simple game in ruby, and I have two arrays storing high score: $HS_Points and $HS_Names. I'm saving high score in two files, and I wanted to encode points a bit (the points are converted with .to_s(23)). I wanted to sort names and scores in descending order and limit them to 10. So, I need to:

Simple points_array.sort won't do, because it will just sort the points, leaving the names in order they were.

Any ideas how to solve that problem? I'd please to keep answer as simple as possible.

Upvotes: 1

Views: 1697

Answers (2)

Michael Slade
Michael Slade

Reputation: 13877

Don't store the names and the scores in separate variables; they're tied together, so their data should be tied togeher.

Try, say, $HighScores, which is an array of hashes with a :name element and a :value element, like:

$HighScores = [  
   { :name => "Bob", :score => 234 },
   { :name => "Mark", :score => 2 },   
]

Then you can add a high score:

$HighScores << { :name => "New Guy", :score => 50000 }

and then re-sort them and take the top 10 in one statement:

$HighScores = $HighScores.sort { |a,b| b[:score] <=> a[:score] }[0,10] 

This will still work if the scores are base-23 encoded. (but why are you doing that?)

You should probably also save them to a single file. To make that easier, consider using the Marshal module.

Upvotes: 0

joelparkerhenderson
joelparkerhenderson

Reputation: 35443

Something like this?

names = ['Alice', 'Bob', 'Carol']
points = [22, 11, 33]

Zip

You may want the Array#zip method:

pairs = names.zip(points)
#=> [["Alice", 22], ["Bob", 11], ["Carol", 33]]

Sort

To sort by an array field, compare two fields of the pair.

Sort by name:

pairs.sort{|x,y| x[0] <=> y[0] }  
#=> [["Alice", 22], ["Bob", 11], ["Carol", 33]]

Sort by score:

pairs.sort{|x,y| x[1] <=> y[1] }  
#=> [["Bob", 11], ["Alice", 22], ["Carol", 33]]

Sort By

Another way to sort is the #sort_by method instead of a comparison block (thanks to Niklas B.)

Sort by name:

pairs.sort_by(&:first) 
#=> [["Alice", 22], ["Bob", 11], ["Carol", 33]]

Sort by score:

pairs.sort_by(&:last)
#=> [["Bob", 11], ["Alice", 22], ["Carol", 33]]

Select

To select just the players above a high score:

pairs.select{|x| x[1] >20 }
#=> [["Alice", 22], ["Carol", 33]]

Unzip

To unzip:

pairs.map(&:first)
#=> ["Alice", "Bob", "Carol"]

pairs.map(&:last)
#=> [22, 11, 33]

These ideas may point you in the right direction.

Upvotes: 10

Related Questions