Как получить список ключей в словаре?

153

Я хочу только ключи, а не значения словаря.

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

Как получить список ключей в словаре?

Ативат Чунлахан
источник

Ответы:

305
List<string> keyList = new List<string>(this.yourDictionary.Keys);
Джамал
источник
6
Нужно ли использовать «это».
JerryGoyal,
15
@JerryGoyal Нет, это не обязательно. Он просто используется для устранения путаницы относительно того, yourDictionaryявляется ли часть объекта производной от функции или именем параметра.
декабря
1
Более полным ответом было бы не предполагать, что тип ключа является строкой. var keyList = yourDictionary.Keys.ToList (); Или, если вы хотите сходить с ума и не использовать var или Linq: - Введите keyType = yourDictionary.GetType (). GetGenericArguments () [0]; Тип listType = typeof (List <>). MakeGenericType (keyType); IList keyList = (IList) Activator.CreateInstance (listType); keyList.AddRange (yourDictionary.Keys);
Энтони Бут
70

Вы должны иметь возможность просто посмотреть на .Keys:

    Dictionary<string, int> data = new Dictionary<string, int>();
    data.Add("abc", 123);
    data.Add("def", 456);
    foreach (string key in data.Keys)
    {
        Console.WriteLine(key);
    }
Марк Гравелл
источник
2
А что, если вы удаляете ключи в цикле?
Мартин Каподичи
5
@MartinCapodici тогда вы обычно должны ожидать, что итератор сломается и откажется продолжать
Марк Гравелл
5
Марк, да, так что в этом случае вы сделаете что-то вроде другого ответа и создадите новый список.
Мартин Каподичи
43

Получить список всех ключей

using System.Linq;
List<String> myKeys = myDict.Keys.ToList();

System.Linq поддерживается в .Net Framework 3.5 или выше. Смотрите ссылки ниже, если у вас возникли проблемы с использованием System.Linq

Visual Studio не распознает System.Linq

Пространство имен System.Linq

прем
источник
13
Пожалуйста, не забывайте: using System.Linq;мне нужно знать, какие ответы игнорировать. Извините :)
Bitterblue
2
Спасибо @Bitterblue. Я не мог понять, почему .ToList()выдает ошибку, когда я использовал его так много раз, поэтому я пришел сюда в поисках ответа и понял, что файл, в котором я работал, не был using System.Linq:)
Дрю
1
не работает:Dictionary<string, object>.KeyCollection' does not contain a definition for 'ToList'
сакра
не работает на самом деле. используйте вместо этого принятый ответ.
сельдь
1
@aleck Отлично работает. Возможно, вы не использовали System.Linq в соответствии с рекомендациями Bitterblue, или используемая вами версия платформы .Net не поддерживает его. Он был введен в .Net Framework 3.5, см. Эту ссылку . Я обновляю ответ, чтобы использовать System.Linq перед использованием этого метода.
прем
12

Ответ Марка Гравелла должен сработать для вас. myDictionary.Keysвозвращает объект, который реализует ICollection<TKey>, IEnumerable<TKey>и их неуниверсальные аналоги.

Я просто хотел добавить, что если вы планируете также получить доступ к значению, вы можете перебрать словарь следующим образом (модифицированный пример):

Dictionary<string, int> data = new Dictionary<string, int>();
data.Add("abc", 123);
data.Add("def", 456);

foreach (KeyValuePair<string, int> item in data)
{
    Console.WriteLine(item.Key + ": " + item.Value);
}
Торарин
источник
3

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

ArrayList lList = new ArrayList(lDict.Keys);
foreach (object lKey in lList)
{
  if (<your condition here>)
  {
    lDict.Remove(lKey);
  }
}

Если бы вы могли использовать общие списки и словари вместо ArrayList, я бы это сделал, однако вышеприведенное должно сработать.

Дэн
источник
2

Я не могу поверить всем этим запутанным ответам. Предполагая, что ключ имеет тип: string (или используйте 'var', если вы ленивый разработчик): -

List<string> listOfKeys = theCollection.Keys.ToList();
Энтони Бут
источник
Что вы имеете в виду, что это не работает? Словарь имеет свойство ключей типа KeyCollection, которое реализует ICollection с методом расширения ToList <> (). Добавьте System.Linq к вашим заявлениям об использовании, и все будет хорошо. using System.linq;
Энтони Бут
0

Или вот так:

List< KeyValuePair< string, int > > theList =
    new List< KeyValuePair< string,int > >(this.yourDictionary);

for ( int i = 0; i < theList.Count; i++)
{ 
  // the key
  Console.WriteLine(theList[i].Key);
}
STH
источник
это создает копию ключей? (так что вы можете спокойно перечислить)
mcmillab
Это переписывает расширение linq .ToList <T> (). Кроме того, список KeyValuePair - это словарь. Первоначальный запрос был только для списка ключей. Использование цикла для заполнения не является необходимым, поскольку List имеет конструктор, который принимает коллекцию, а также имеет метод AddRange () для добавления в существующий List. Смотрите принятый ответ.
Энтони Бут
0

Для гибридного словаря я использую это:

List<string> keys = new List<string>(dictionary.Count);
keys.AddRange(dictionary.Keys.Cast<string>());
Косма
источник
-2

Я часто использовал это, чтобы получить ключ и значение в словаре: (VB.Net)

 For Each kv As KeyValuePair(Of String, Integer) In layerList

 Next

(layerList имеет тип Dictionary (Of String, Integer))

Джозеф Ву
источник