Question

I have a SortedDictionary where I am holding points of a particular player and his name next to it. What I need to do is to sort this in a descending order so that I have the winner in the first position of the dictionary. How can I do that?

Also, how can I get an item from the list without knowing the key?

SortedDictionary<int, string> dict = new SortedDictionary<int, string>();
dict.Add(player1Pts, playerNames[0]);
dict.Add(player2Pts, playerNames[1]);
dict.Add(player3Pts, playerNames[2]);

Thanks for any help!

Was it helpful?

Solution

It doesn't really make sense to use a dictionary with the score as the key: the key must be unique, so it will fail if two players have the same score.

Instead, you should create a Player class that contains the name and score, and store Player objects in a List<Player>. If you need to sort the players by score, you can call Sort on the list with a custom comparer, or just order the result with Linq:

foreach (Player player in players.OrderByDescending(p => p.Score))
{
    // Do something with player
}

OTHER TIPS

First: A Sorted Dictionary will always be sorted immediately, when you insert another Value.

But note: Using the points as KEY means that you cannot have players with EQUAL points.

But if you want to go with that, you can simple use the Last() Method of your Dictionary to get the player with the most points:

SortedDictionary<int, String> t = new SortedDictionary<int,string>();
t.Add(5, "a");
t.Add(10, "c");
t.Add(2, "b");
MessageBox.Show((t.Last<KeyValuePair<int,string>>()).Value);

This Will Result in "c".

For first I think you should switch places of <int, string> player name should be key, and points would be values.

Then you can sort it by values:

dict.Sort(
    delegate(KeyValuePair<int, double> val1,
    KeyValuePair<int, double> val2)
    {
        return val1.Value.CompareTo(val2.Value);
    }
);

You can go through the dictionary by foreach to get keys and values:

 foreach (var pair in asd)
            {
                string some = pair.Key;
                int someValue =  pair.Value;
            }

The answer to my problem was this to anyone who might need it :)

Player player1 = new Player(playerNames[0], player1Pts);
Player player2 = new Player(playerNames[1], player2Pts);
Player player3 = new Player(playerNames[2], player3Pts);
Player player4 = new Player(playerNames[3], player4Pts);
Player player5 = new Player(playerNames[4], player5Pts);

List<Player> players = new List<Player>();

players.Add(player1);
players.Add(player2);
players.Add(player3);
players.Add(player4);
players.Add(player5);

var sortedPlayers = (from Player play in players
                     orderby play.Points descending
                     select play);

List<Player> sortPlay = (List<Player>)sortedPlayers.ToList();

While there are several answers to the question, none of these seem to take advantage of the SortedDictionary structure. If you want the SortedDictionary to be designed as a max heap rather than the default min heap, I think the best solution is to overwrite the default comparer that C# uses. This can be done as follows:

public class DescendingComparer<T>: IComparer<T> where T : IComparable<T>
{
    public int Compare(T x, T y)
    {
        return y.CompareTo(x); //reverses, so compare ascending
                 //this is vs the standard method, which returns x.CompareTo(y)
    }

}

static void Main(string[] args)
{

SortedDictionary<float, string> myDict = new SortedDictionary<float,string>(new DescendingComparer<float>()); //sorts on the key
    string[] name = {"Bill", "Tom", "Susan", "Terry"};
    myDict.Add(.8f, name[0]);
    myDict.Add(.2f, name[1]);
    myDict.Add(.95f, name[2]);
    myDict.Add(.005f, name[4]);

    foreach (KeyValuePair<float, int> j in myDict)
    {
        Console.WriteLine("Key: {0}, Value: {1}",j.Key,j.Value);
    } //now it is stored in increasing order, so accessing largest elements fast
}

See also, here: C#: sort dictionary in descending order

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top