Подтвердить что ты не робот

Получить последний элемент в словаре?

Мой словарь:

Dictionary<double, string> dic = new Dictionary<double, string>();

Как я могу вернуть последний элемент в словаре?

4b9b3361

Ответ 1

Что вы подразумеваете под Last? Вы имеете в виду последнюю добавленную стоимость?

Класс Dictionary<TKey,TValue> является неупорядоченной коллекцией. Добавление и удаление элементов может изменить то, что считается первым и последним элементом. Следовательно, нет способа получить последний элемент.

Существует класс упорядоченного словаря, доступный в форме SortedDictionary<TKey,TValue>. Но это будет упорядочено на основе сравнения ключей, а не с порядком добавления значений.

EDIT

Несколько человек упомянули использование следующего подхода стиля LINQ

var last = dictionary.Values.Last();

Будьте очень осторожны в использовании этого метода. Он вернет последнее значение в коллекции значений. Это может быть или не быть последним значением, которое вы добавили в словарь. Вероятно, это не так, как должно быть.

Ответ 2

Словари - это неупорядоченные коллекции - как таковые, нет понятия первого или последнего элемента. Если вы ищете класс, который ведет себя как словарь, но поддерживает порядок вставки элементов, рассмотрите возможность использования OrderedDictionary.

Если вы ищете коллекцию, сортирующую элементы, рассмотрите возможность использования SortedDictionary<TKey,TValue>.

Если у вас есть существующий словарь, и вы ищете "последний" элемент, заданный в некотором порядке сортировки, вы можете использовать linq для сортировки коллекции, например:

myDictionary.Values.OrderBy( x => x.Key ).Last();

С осторожностью использовать Dictionary.Keys.Last() - в то время как список ключей сортируется по умолчанию IComparer для типа ключа, значение, которое вы получаете, может не соответствовать ожидаемому значению.

Ответ 3

Я знаю, что этот вопрос слишком велик, чтобы получить какие-либо авансы, но мне не понравился ни один из ответов, поэтому опубликуйте свои собственные в надежде предложить другой вариант будущим читателям.

Для .NET 4.0 не работало следующее:

myDictionary.Values.OrderBy( x => x.Key ).Last();

Я подозреваю, что проблема заключается в том, что "x" представляет значение в словаре, а значение не имеет ключа (словарь хранит ключ, значения словаря - нет). Я также могу ошибаться в использовании этой техники.

В любом случае это решение будет медленным для больших словарей, возможно, O (n log n) для пользователей CS, потому что это сортировка всего словаря только для получения одной записи. Это похоже на переупорядочение всей вашей коллекции DVD, чтобы найти один конкретный фильм.


var lastDicVal = dic.Values.Last();

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


Мое решение таково:

var lastValue = dic[dic.Keys.Max()];

Функция Keys.max() намного быстрее, чем сортировка O (n) вместо O (n log n). Если производительность достаточно важна, даже если O (n) слишком медленный, последний вставленный ключ можно отследить в отдельной переменной, используемой для замены dic.Keys.Max(), которая сделает весь поиск O (1) плюс любые накладные расходы существует в отслеживании последней вставленной записи.

Ответ 4

Если вы используете .NET 3.5, посмотрите:

 dic.Keys.Last()

Если вы хотите предсказуемый порядок, используйте:

IDictionary<int, string> dic = new SortedDictionary<int, string>();

Ответ 5

Рассмотрим создание пользовательской коллекции, содержащей ссылку в методе Add пользовательской коллекции. Это установило бы личное поле, содержащее последний добавленный ключ/значение (или оба) в зависимости от ваших требований.

Затем следует метод Last(), который возвращает это. Здесь доказательство класса концепции, чтобы показать, что я имею в виду (пожалуйста, не стучите в отсутствие реализации интерфейса и т.д. Это пример кода):

public class LastDictionary<TKey, TValue>
{
    private Dictionary<TKey, TValue> dict;

    public LastDictionary()
    {
        dict = new Dictionary<TKey, TValue>();
    }

    public void Add(TKey key, TValue value)
    {
        LastKey = key;
        LastValue = value;
        dict.Add(key, value);
    }

    public TKey LastKey
    {
        get; private set;
    }

    public TValue LastValue
    {
        get; private set;
    }
}

Ответ 6

Вместо использования:

Dictionary<double, string>

... вы можете использовать:

List<KeyValuePair<double, string>>

Это позволит вам использовать индексатор для доступа к элементу по порядку, а не по ключу.

Ответ 7

Из docs:

Для целей перечисления каждый элемент в словаре рассматривается как Структура KeyValuePair, представляющая значение и его ключ. Порядок, в котором элементы возвращаются undefined.

Итак, я не думаю, что вы можете положиться на Dictionary, чтобы вернуть последний элемент.

Используйте другую коллекцию. Может быть, SortedDictionary...

Ответ 8

Если вам просто нужно значение, это должно работать (при условии, что вы можете использовать LINQ):

dic.Values.Last()

Ответ 9

Вы можете использовать:

dic.Last()

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

Ответ 10

С .Net 3.5:

string lastItem = dic.Values.Last()
string lastKey = dic.Keys.Last()

... но имейте в виду, что словарь не упорядочен, поэтому вы не можете рассчитывать на то, что значения останутся в том же порядке.

Ответ 11

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

Dictionary<double, string> dic = new Dictionary<double, string>();
double highest = double.MinValue;
string result = null;
foreach(double d in dic.keys)
{
   if(d > highest)
   {
      result = dic[d];
      highest = d;
   }
}

Ответ 12

Вместо использования Linq, как и большинство других ответов, вы можете просто получить доступ к последнему элементу любого объекта Collection через свойство Count (см. ICollection.Count Свойство для получения дополнительной информации).

См. здесь код для примера использования count для доступа к последнему элементу в любой коллекции (включая словарь):

Dictionary<double, string> dic = new Dictionary<double, string>();
var lastElementIndex = dic.Count - 1;
var lastElement = dic[lastElementIndex];

Имейте в виду, что это возвращает последнее VALUE, а не ключ.