SortedDictionary в C#

У меня есть SortedDictionary, где я держу очки конкретного игрока и его имя рядом с ним. Что мне нужно сделать, так это отсортировать это в порядке убывания, чтобы у меня был победитель на первой позиции словаря. Как я могу это сделать?

Кроме того, как я могу получить элемент из списка, не зная ключа?

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

Спасибо за любую помощь!


person Bernice    schedule 06.12.2012    source источник
comment
Так как же узнать, какой предмет получить?   -  person Jakub Konecki    schedule 06.12.2012
comment
Большая проблема, с которой вы сталкиваетесь при использовании SortedDictionary, заключается в том, что у вас не может быть двух игроков с одинаковым счетом. Словарь не позволит вам добавить дубликат счета. Возможно, вам нужно посмотреть на альтернативную структуру данных?   -  person Enigmativity    schedule 06.12.2012


Ответы (5)


На самом деле не имеет смысла использовать словарь со счетом в качестве ключа: ключ должен быть уникальным, поэтому он не сработает, если у двух игроков будет одинаковый счет.

Вместо этого вы должны создать класс Player, содержащий имя и оценку, и хранить Player объектов в классе List<Player>. Если вам нужно отсортировать игроков по счету, вы можете вызвать Sort в списке с помощью специального компаратора или просто упорядочить результат с помощью Linq:

foreach (Player player in players.OrderByDescending(p => p.Score))
{
    // Do something with player
}
person Thomas Levesque    schedule 06.12.2012
comment
Да, ты прав! Иногда я иду на что-то более сложное, когда это может быть просто так! Спасибо за вашу помощь :) - person Bernice; 06.12.2012
comment
List‹Player› sortedPlayers = (от Player play in player orderby play.Очки по убыванию выберите игру) как List‹Player›; Не могли бы вы объяснить, почему это возвращает null вместо отсортированных игроков? :/ - person Bernice; 06.12.2012
comment
@studentProgrammer, поскольку запрос возвращает IEnumerable<Player>, а не List<Player>, поэтому приведение с as завершается ошибкой и возвращает значение null. Вместо этого используйте .ToList(). - person Thomas Levesque; 06.12.2012

Во-первых: Сортированный словарь всегда будет отсортирован немедленно, когда вы вставите другое значение.

Но обратите внимание: использование очков в качестве КЛЮЧА означает, что у вас не может быть игроков с РАВНЫМИ очками.

Но если вы хотите пойти с этим, вы можете просто использовать метод Last() вашего словаря, чтобы получить игрока с наибольшим количеством очков:

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);

Это приведет к "c".

person dognose    schedule 06.12.2012

Во-первых, я думаю, вы должны поменять местами <int, string> имя игрока должно быть ключевым, а очки будут значениями.

Затем вы можете отсортировать его по значениям:

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

Вы можете просмотреть словарь с помощью foreach, чтобы получить ключи и значения:

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

Ответ на мою проблему был таким, кому это может понадобиться :)

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();
person Bernice    schedule 06.12.2012

Хотя на этот вопрос есть несколько ответов, ни один из них, похоже, не использует структуру SortedDictionary. Если вы хотите, чтобы SortedDictionary был спроектирован как максимальная куча, а не минимальная куча по умолчанию, я думаю, что лучшим решением будет перезаписать компаратор по умолчанию, который использует С#. Это можно сделать следующим образом:

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
}

См. также здесь: C#: сортировка словаря в порядке убывания

person Notarobot2244    schedule 29.07.2016