I have multiple arrays that I need to sort by one array. The way I have this setup is one array has player names, another has points earned and a third has player id’s. After a race I need to use the player id to add the points to the proper player using the id. Now here I sort the points highest to lowest, which I know how to do, but I also want the player name and player id to reorder to the same location in their respective array. So if points[3] is now points[0] i want player[3] to be player[0] and playerId[3] is playerId[0]. I have seen other posts like this one but cannot get any of them to do what I am looking for. I see on MSDN there are functions to do this sort of thing but I cannot get them to work in unity. Array.Sort Method (System) | Microsoft Learn
Please if I am going about this the wrong way point me in the correct direction. Any help would be excellent. Thank you!
You would need to do your sorting manually and make sure you’re changing the elements of all three arrays but this is not the most efficient. You should instead use a class or a struct but there are some important things to note. Since the struct is not a reference type you’ll need to reset it in the array. Here are the methods you could do:
CLASS APPROACH
public class Player {
public string Id { get; set; }
public int Score { get; set; }
public string PlayerName { get; set; }
}
Now, consider using something like a Dictionary<string, Player> where the key is the PlayerId, so you could do:
var players = new Dictionary<string, Player>();
for(var i = 0; i < 5; i++)
{
var p = new Player();
p.Name = string.Format("Player-{0}", i);
p.Id = i;
p.Score = 0;
players.Add(p);
}
Now you want to update the score of the player with the Id of “4” so you can:
players["4"].Score += 10;
Now you can sort it with LINQ as follows:
//Order the dictionary by Score which returns IEnumerable<KeyValuePair>
//Then return as dictionary using Id as the Key.
players = players.OrderBy(p => p.Value.Score).ToDictionary(p => p.Value.Id);
Now you could also create your own comparer and use .Sort to do it which I would actually recommend for performance as it would be a bit faster than using LINQ. You could also just use a List or Player[ ] array and just iterate through and find the player with the correct Id, though lookups are faster on the Dictionary if you’re always looking for the player by Id. If you need it to be case-insensitive you’ll specify the ordinal compare as case insensitive when you declare the dictionary.
STRUCT APPROACH
To use a struct you would do exactly as above except with a couple minor differences.
Declare as struct:
public struct Player {
public string Id { get; set; }
public int Score { get; set; }
public string PlayerName { get; set; }
}
And since it’s a value type… to update the score:
var player = players["4"];
player.Score += 10;
players["4"] = player;
Thank you very much for the input. It was really simple and since my data amount is tiny I went with manually sorting the arrays. Googled a selection sort and modified it to work with my needs. Thanks again.
For anyone else out there who wants it, this code allowed me to sort three arrays by the score value in descending order.
function SortScores (scores : float[], names : String[], id : int[])
{
var tmp : float;
var tmp2 : float;
var tmpName : String;
var tmpid : int;
for (var i = 0; i < scores.length - 1; i++)
{
tmp = i;
for (var j = i + 1; j < scores.length; j++)
if (scores[j] > scores[tmp])
tmp = j;
//Assign Holders for all objects
tmp2 = scores[tmp];
tmpName = names[tmp];
tmpid = id[tmp];
//Swap places
scores[tmp] = scores[i];
scores[i] = tmp2;
names[tmp] = names[i];
names[i] = tmpName;
id[tmp] = id[i];
id[i] = tmpid;
}
}