Я использую Dictionary<string, int>
где int
это количество ключей.
Теперь мне нужно получить доступ к последнему вставленному ключу внутри словаря, но я не знаю его названия. Очевидная попытка:
int LastCount = mydict[mydict.keys[mydict.keys.Count]];
не работает, потому Dictionary.Keys
что не реализует [] -индексер.
Мне просто интересно, есть ли подобный класс? Я думал об использовании стека, но он хранит только строку. Теперь я мог бы создать свою собственную структуру, а затем использовать a Stack<MyStruct>
, но мне интересно, есть ли другая альтернатива, по сути, Dictionary, который реализует [] -индексор для ключей?
c#
.net
dictionary
Майкл Стум
источник
источник
Ответы:
Как отмечает @Falanwe в комментарии, делать что-то подобное неправильно :
Вы не должны зависеть от порядка ключей в словаре. Если вам нужно упорядочить, вы должны использовать OrderedDictionary , как предлагается в этом ответе . Другие ответы на этой странице также интересны.
источник
HashTable
System.Collections.ICollection ', не содержит определения для' ElementAt 'и не найден метод расширения' ElementAt ', принимающий первый аргумент типа' System.Collections.ICollection 'ElementAtOrDefault
версию для работы с исключительной версией.Dictionary<TKey,TValue>
документации, «порядок ключей вDictionary<TKey, TValue>.KeyCollection
не указан».mydict.Count -1
Вы можете использовать OrderedDictionary .
источник
Словарь - это хеш-таблица, поэтому вы не знаете, как вставить код!
Если вы хотите узнать последний вставленный ключ, я бы предложил расширить словарь, включив в него значение LastKeyInserted.
Например:
Вы столкнетесь с проблемами, однако, когда вы будете использовать
.Remove()
это, чтобы преодолеть это, вам придется хранить упорядоченный список вставленных ключей.источник
Почему бы вам просто не расширить класс словаря, чтобы добавить в него вставленное свойство последнего ключа. Может быть, что-то вроде следующего?
источник
Вы всегда можете сделать это:
Но я бы не рекомендовал это. Нет гарантии, что последний вставленный ключ будет в конце массива. Порядок ключей на MSDN не указан и может быть изменен. В моем очень коротком тесте это, кажется, в порядке вставки, но вам лучше бы построить правильную бухгалтерию, например, стеком - как вы предлагаете (хотя я не вижу необходимости в структуре, основанной на ваших другие операторы) - или кеш одной переменной, если вам просто нужно знать последний ключ.
источник
Я думаю, что вы можете сделать что-то вроде этого, синтаксис может быть неправильным, не использовал C # некоторое время, чтобы получить последний элемент
или используйте Max вместо Last, чтобы получить максимальное значение, я не знаю, какой из них лучше подходит вашему коду.
источник
Я согласен со второй частью ответа Патрика. Даже если в некоторых тестах, похоже, сохраняется порядок вставки, в документации (и нормальном поведении для словарей и хешей) явно указывается, что порядок не указан.
Вы просто напрашиваетесь на неприятности в зависимости от порядка ключей. Чтобы быть уверенным, добавьте свою собственную бухгалтерию (как сказал Патрик, только одну переменную для последнего добавленного ключа). Кроме того, не поддавайтесь соблазну всеми методами, такими как Last и Max в словаре, так как они, вероятно, относятся к ключевому компаратору (я не уверен в этом).
источник
В случае, если вы решите использовать опасный код, который может быть поврежден, эта функция расширения будет извлекать ключ из a
Dictionary<K,V>
согласно его внутренней индексации (которая для Mono и .NET в настоящее время выглядит в том же порядке, что и вы, перечисляяKeys
свойство ).Гораздо предпочтительнее использовать Linq:,
dict.Keys.ElementAt(i)
но эта функция будет повторять O (N); следующее O (1), но с ухудшением производительности отражения.источник
Одной из альтернатив будет KeyedCollection, если ключ встроен в значение.
Просто создайте базовую реализацию в закрытом классе для использования.
Таким образом, чтобы заменить
Dictionary<string, int>
(что не очень хороший пример, так как нет ясного ключа для int).источник
То, как вы сформулировали вопрос, заставляет меня поверить, что int в Словаре содержит «позицию» элемента в Словаре. Судя по утверждению о том, что ключи хранятся не в том порядке, в котором они были добавлены, если это правильно, это будет означать, что keys.Count (или .Count - 1, если вы используете нули) должны по-прежнему всегда будет номер последнего введенного ключа?
Если это правильно, есть ли причина, по которой вы не можете вместо этого использовать Dictionary <int, string>, чтобы вы могли использовать mydict [mydict.Keys.Count]?
источник
Я не знаю, сработает ли это, потому что я почти уверен, что ключи хранятся не в том порядке, в котором они были добавлены, но вы можете привести KeysCollection к списку, а затем получить последний ключ в списке ... но стоило бы посмотреть.
Единственное, о чем я могу подумать, это сохранить ключи в списке поиска и добавить ключи в список, прежде чем добавлять их в словарь ... это не совсем так.
источник
Чтобы подробнее остановиться на публикации Дэниелса и его комментариях относительно ключа, поскольку ключ в любом случае встроен в значение, вы можете прибегнуть к использованию в
KeyValuePair<TKey, TValue>
качестве значения. Основная причина этого заключается в том, что в общем случае ключ не обязательно напрямую выводится из значения.Тогда это будет выглядеть так:
Чтобы использовать это, как в предыдущем примере, вы должны сделать:
источник
Словарь может быть не очень интуитивно понятным для использования индекса для справки, но вы можете выполнять аналогичные операции с массивом KeyValuePair :
ех.
KeyValuePair<string, string>[] filters;
источник
Вы также можете использовать SortedList и его общий аналог. Эти два класса и упомянутый в ответе Эндрю Питерса OrderedDictionary являются словарными классами, в которых элементы могут быть доступны по индексу (позиции), а также по ключу. Как использовать эти классы вы можете найти: SortedList Class , SortedList Generic Class .
источник
UserVoice Visual Studio дает ссылку на универсальную реализацию OrderedDictionary от dotmore.
Но если вам нужно только получить пары ключ / значение по индексу и не нужно получать значения по ключам, вы можете использовать один простой прием. Объявите некоторый универсальный класс (я назвал его ListArray) следующим образом:
Вы также можете объявить это с помощью конструкторов:
Например, вы читаете некоторые пары ключ / значение из файла и просто хотите сохранить их в том порядке, в котором они были прочитаны, чтобы получить их позже по индексу:
Как вы, возможно, заметили, вы не обязательно можете иметь просто пары ключ / значение в вашем ListArray. Массивы элементов могут быть любой длины, например, в зубчатом массиве.
источник