Доступ к ключу Dictionary.Keys через числовой индекс - PullRequest
147 голосов
/ 07 августа 2008

Я использую Dictionary<string, int>, где int - это число ключей.

Теперь мне нужен доступ к последнему вставленному ключу внутри словаря, но я не знаю его имени. Очевидная попытка:

int LastCount = mydict[mydict.keys[mydict.keys.Count]];

не работает, потому что Dictionary.Keys не реализует [] -индексор.

Мне просто интересно, есть ли подобный класс? Я думал об использовании стека, но он хранит только строку. Теперь я мог бы создать свою собственную структуру и затем использовать Stack<MyStruct>, но мне интересно, есть ли другая альтернатива, по существу, Словарь, который реализует [] -индексор на Ключах?

Ответы [ 15 ]

2 голосов
/ 07 апреля 2016

Словарь может быть не очень интуитивно понятным для использования индекса для справки, но вы можете выполнять аналогичные операции с массивом KeyValuePair :

ех. KeyValuePair<string, string>[] filters;

2 голосов
/ 25 марта 2015

Вы также можете использовать SortedList и его общий аналог. Эти два класса и упомянутый в ответе Эндрю Питерса OrderedDictionary являются словарными классами, в которых элементы могут быть доступны по индексу (позиции), а также по ключу. Как использовать эти классы вы можете найти: SortedList Class , SortedList Generic Class .

2 голосов
/ 20 июля 2011

Более подробно о публикации Дэниелса и его комментариях относительно ключа, поскольку ключ в любом случае встроен в значение, вы можете прибегнуть к использованию KeyValuePair<TKey, TValue> в качестве значения. Основная причина этого заключается в том, что в общем случае ключ не обязательно напрямую выводится из значения.

Тогда это будет выглядеть так:

public sealed class CustomDictionary<TKey, TValue>
  : KeyedCollection<TKey, KeyValuePair<TKey, TValue>>
{
  protected override TKey GetKeyForItem(KeyValuePair<TKey, TValue> item)
  {
    return item.Key;
  }
}

Чтобы использовать это, как в предыдущем примере, вы должны сделать:

CustomDictionary<string, int> custDict = new CustomDictionary<string, int>();

custDict.Add(new KeyValuePair<string, int>("key", 7));

int valueByIndex = custDict[0].Value;
int valueByKey = custDict["key"].Value;
string keyByIndex = custDict[0].Key;
2 голосов
/ 07 августа 2008

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

Единственное, о чем я могу думать, это сохранить ключи в списке поиска и добавить ключи в список, прежде чем добавлять их в словарь ... это не очень хорошо.

1 голос
/ 03 ноября 2016

Visual Studio UserVoice дает ссылку на универсальную реализацию OrderedDictionary от dotmore.

Но если вам нужно только получить пары ключ / значение по индексу и не нужно получать значения по ключам, вы можете использовать один простой прием. Объявите некоторый универсальный класс (я назвал его ListArray) следующим образом:

class ListArray<T> : List<T[]> { }

Вы также можете объявить это с помощью конструкторов:

class ListArray<T> : List<T[]>
{
    public ListArray() : base() { }
    public ListArray(int capacity) : base(capacity) { }
}

Например, вы читаете некоторые пары ключ / значение из файла и просто хотите сохранить их в том порядке, в котором они были прочитаны, чтобы потом получить их по индексу:

ListArray<string> settingsRead = new ListArray<string>();
using (var sr = new StreamReader(myFile))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        string[] keyValueStrings = line.Split(separator);
        for (int i = 0; i < keyValueStrings.Length; i++)
            keyValueStrings[i] = keyValueStrings[i].Trim();
        settingsRead.Add(keyValueStrings);
    }
}
// Later you get your key/value strings simply by index
string[] myKeyValueStrings = settingsRead[index];

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

...