Reputation: 213
I have a dictionary which stores members of a 'Skiing' tournament. It also stores there scores. What I want to do is be able to find and display the top 3 scores of the members. I was just wondering what the best way would be to approach this as I am stuck at the moment. The following is the dictionary and how a member is added:
public static Dictionary<string, Skier> Skiers = new Dictionary<string, Skier>();
static int income;
string lodgeName;
public SkiLodge(string newLodgeName)
{
newLodgeName = lodgeName;
Skiers = new Dictionary<string, Skier>();
}
static int newNumber = 1;
//ADD SKIER
public Skier AddSkier(string inName, string inAddress, int inScore)
{
string newNumberString = newNumber.ToString();
Skier result = new Skier(newNumberString, inName, inAddress, inScore);
newNumber = newNumber + 1;
Skier S = new Skier(newNumberString, inName, inAddress, inScore);
Skiers.Add(newNumberString, S);
income = income + 100;
return result;
}
Upvotes: 2
Views: 180
Reputation: 2185
Either of these methods added to your SkiLodge
class, will get you what you're looking for.
This will grab your top X KeyValuePairs with the Skier
object being the Value
property of the KeyValuePair
.
public List<KeyValuePair<string,Skier>> GetTopSkiers(int howMany)
{
return Skiers.OrderByDescending(kvp => kvp.Value.Score).Take(howMany).ToList();
}
This will grab your top X Skiers
public List<Skier> GetTopSkiers(int howMany)
{
return Skiers.OrderByDescending(kvp => kvp.Value.Score).Take(howMany).Select(kvp => kvp.Value).ToList();
}
Both methods use the OrderByDescending Linq method, which uses a lambda expression as a selector for the sorting comparison kvp => kvp.Value.Score
. Which in this case is saying, foreach kvp (KeyValuePair
) in this dictionary, sort them by the Value
property, which in this case is the Skier
object, and use the Skier object's Score
as the value to sort by.
Take will take, up to x values from an Enumerable
.
Select then returns an Enumerable
resulting from the lambda function passed in. In this case, kvp => kvp.Value
returns an Enumerable
of Skier
objects, instead of a list of the KeyValuePair
objects.
Upvotes: 3
Reputation: 646
Using System.Linq, the following code will get you the best 3 Skiers by score:
public List<Skier> GetTop3()
{
var list = Skiers.OrderByDescending(sk=> sk.Value.Score).Take(3).ToList();
return list;
}
Upvotes: 1
Reputation: 885
You may use LINQ to achieve. Here is one sample query:
Skiers.OrderByDescending(e=>e.Value.inScore).Take(3).ToList();
Upvotes: 1
Reputation: 34421
Either use a SortedDictionary or enumerate through the keys of dictionary or this code
public class Skier
{
public static Dictionary<string, Skier> Skiers = new Dictionary<string, Skier>();
public int inScore { get; set; }
public Skier()
{
int[] highscore = Skiers.AsEnumerable().OrderByDescending(x => ((Skier)x.Value).inScore).Take(3).Select(y => ((Skier)y).inScore).ToArray();
}
}
Upvotes: 1
Reputation: 654
I have tried to replicate the behavior and fixed some of the issues in above code. In AddSkier you dont need to create 2 objects. FetchTopThree() will give you the top 3 results. You can then display the results.
using System.Collections.Generic;
using System.Linq;
public class SkiLodge
{
public static Dictionary<string, Skier> Skiers = new Dictionary<string, Skier>();
static int income;
string lodgeName;
public SkiLodge(string newLodgeName)
{
this.lodgeName = newLodgeName;
}
static int newNumber = 1;
//ADD SKIER
public Skier AddSkier(string inName, string inAddress, int inScore)
{
string newNumberString = newNumber.ToString();
newNumber = newNumber + 1;
Skier skier= new Skier(newNumberString, inName, inAddress, inScore);
Skiers.Add(newNumberString, skier);
income = income + 100;
return skier;
}
public List<Skier> FetchTopThree()
{
return Skiers.Values.OrderByDescending(s => s.InScore).Take(3).ToList();
}
}
public class Skier
{
public string NewNumberString { get; }
public string InName { get; }
private readonly string inAddress;
public int InScore { get; }
public Skier(string newNumberString, string inName, string inAddress, int inScore)
{
this.NewNumberString = newNumberString;
this.InName = inName;
this.inAddress = inAddress;
this.InScore = inScore;
}
}
Upvotes: 0
Reputation: 1473
I assumed that you have a property in Skier called Score, here how can you achieve your goal.
//Your dictionary must have at least 3 entries.
var orderedTopThree = Skiers.OrderByDescending(s => s.Value.Score).Take(3);
Upvotes: 7