Search code examples
c#functionsortingleaderboard

C# multiple variable leaderboard


I am making a script in c# and it needs a function to create a leaderboard using multiple parameters. Here is an example of one of the leaderboards :
1
The bold column is the first check for the leaderboard, and then it moves on to the column on the left, and so on.

My idea was to make a for loop for each column and sort the four values.

int[] tempScores = new int[scores[0].Length];
for (int i = 0; i < scores[0].Length; i++)
{
  if (scores[0][i] < scores[0][i+1]) tempScores[i] = scores[0][i+1];
  else if (scores[0][i] > scores[0][i+1]) tempScores[i] = scores[0][i];
  else if (scores[0][i] == scores[0][i+1])
  {
    // Do same thing but for next column : scores[1]
  }
}

This code would work 90% on the time but sometimes two or more of the values are inverted. And it just does not work for a leaderboard like this :
2

So if anyone would have an answer to my problem or a more efficient way to do it I would love to know how.


Solution

  • I read this and the first thing that came to my mind is Linq. All you need to do is order by the first property you care about and then by all the other ones.

    First thing is to create a class which can hold your Country data.

    It could look something like this :

    public class CountryData
        {
            public string Name { get; set; }
            public int Prop1 { get; set; }
            public int Prop2 { get; set; }
            public int Prop3 { get; set; }
            public int Prop4 { get; set; }
            public int Prop5 { get; set; }
            public int Prop6 { get; set; }
            public int Prop7 { get; set; }
            public int Prop8 { get; set; }
        }
    

    I don't know what those properties mean as you don't say so I gave them a generic name for now. You can always change it to something more meaningful

    Ok, now that we have this we need the actual ordering.

    We could write another class to do this :

    public class OrderLogic
        {
            public List<CountryData>  SortCountries(List<CountryData> countriesData)
            {
                return countriesData
                    .OrderByDescending(p => p.Prop8)
                    .ThenByDescending(p => p.Prop7) //continue with as many orders as you need
                    .ToList();
            }
        }
    

    Finally, how do we use it?

    I would write a test for this, to make sure the logic works well:

    [Test]
            public void Test1()
            {
                List<CountryData> countriesData = new List<CountryData>();
    
                countriesData.Add(new CountryData { Name = "Switzerland", Prop1 = 3, Prop2 = 1, Prop3 = 1, Prop4 = 1, Prop5 = 4, Prop6 = 5, Prop7 = -1, Prop8 = 4 });
                countriesData.Add(new CountryData { Name = "Italy", Prop1 = 3, Prop2 = 3, Prop3 = 0, Prop4 = 0, Prop5 = 7, Prop6 = 0, Prop7 = 7, Prop8 = 9 });
                countriesData.Add(new CountryData { Name = "Wales", Prop1 = 3, Prop2 = 1, Prop3 = 1, Prop4 = 1, Prop5 = 3, Prop6 = 2, Prop7 = 1, Prop8 = 4 });            
                countriesData.Add(new CountryData { Name = "Turkey", Prop1 = 3, Prop2 = 0, Prop3 = 0, Prop4 = 3, Prop5 = 1, Prop6 = 8, Prop7 = -7, Prop8 = 0 });
    
                var result = new OrderLogic().SortCountries(countriesData);
    
                Assert.IsTrue(result[0].Name.Equals("Italy"));
                Assert.IsTrue(result[1].Name.Equals("Wales"));
                Assert.IsTrue(result[2].Name.Equals("Switzerland"));
                Assert.IsTrue(result[3].Name.Equals("Turkey"));
            }
    

    And there you go, the test passes, you can refactor to your heart's content knowing that you won't break the actual logic.