Каков наилучший способ перебора словаря? - PullRequest
2264 голосов
/ 26 сентября 2008

Я видел несколько разных способов перебора словаря в C #. Есть ли стандартный способ?

Ответы [ 26 ]

11 голосов
/ 28 октября 2009

Вы предложили ниже повторить

Dictionary<string,object> myDictionary = new Dictionary<string,object>();
//Populate your dictionary here

foreach (KeyValuePair<string,object> kvp in myDictionary) {
    //Do some interesting things;
}

К вашему сведению, foreach не работает, если значение имеет тип объекта.

10 голосов
/ 17 октября 2017

С .NET Framework 4.7 можно использовать разложение

var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
    Console.WriteLine(fruit + ": " + number);
}

Чтобы этот код работал на более низких версиях C #, добавьте System.ValueTuple NuGet package и напишите куда-нибудь

public static class MyExtensions
{
    public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple,
        out T1 key, out T2 value)
    {
        key = tuple.Key;
        value = tuple.Value;
    }
}
8 голосов
/ 27 мая 2018

Используя C # 7 , добавьте метод расширения к любому проекту вашего решения:

public static class IDictionaryExtensions
{
    public static IEnumerable<(TKey, TValue)> Tuples<TKey, TValue>(
        this IDictionary<TKey, TValue> dict)
    {
        foreach (KeyValuePair<TKey, TValue> kvp in dict)
            yield return (kvp.Key, kvp.Value);
    }
}


И используйте этот простой синтаксис

foreach (var(id, value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}


Или этот, если вы предпочитаете

foreach ((string id, object value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}


На месте традиционного

foreach (KeyValuePair<string, object> kvp in dict)
{
    string id = kvp.Key;
    object value = kvp.Value;

    // your code using 'id' and 'value'
}


Метод расширения преобразует KeyValuePair вашего IDictionary<TKey, TValue> в строго типизированный tuple, что позволяет вам использовать этот новый удобный синтаксис.

Он преобразует -just- необходимые словарные записи в tuples, поэтому он НЕ преобразует весь словарь в tuples, поэтому никаких проблем с производительностью, связанных с этим.

Существует только незначительная стоимость вызова метода расширения для создания tuple по сравнению с использованием KeyValuePair напрямую, что НЕ должно быть проблемой, если вы присваиваете KeyValuePair свойства Key и Value к новым переменным цикла в любом случае.

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

Проверьте это: Блог MSDN - Новые функции в C # 7

8 голосов
/ 02 октября 2016

Простейшая форма для перебора словаря:

foreach(var item in myDictionary)
{ 
    Console.WriteLine(item.Key);
    Console.WriteLine(item.Value);
}
6 голосов
/ 02 июля 2014

Иногда, если вам нужно только перечислить значения, используйте коллекцию значений словаря:

foreach(var value in dictionary.Values)
{
    // do something with entry.Value only
}

Об этом сообщает этот пост, в котором говорится, что это самый быстрый метод: http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html

5 голосов
/ 18 февраля 2009

Я нашел этот метод в документации для класса DictionaryBase на MSDN:

foreach (DictionaryEntry de in myDictionary)
{
     //Do some stuff with de.Value or de.Key
}

Это была единственная возможность правильно работать в классе, унаследованном от DictionaryBase.

3 голосов
/ 11 июля 2018

Начиная с C # 7, вы можете деконструировать объекты в переменные. Я считаю, что это лучший способ перебора словаря.

Пример:

Создайте метод расширения на KeyValuePair<TKey, TVal>, который его деконструирует:

public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey, out TVal val)
{
   key = pair.Key;
   val = pair.Value;
}

Выполните итерацию по любому Dictionary<TKey, TVal> следующим образом

// Dictionary can be of any types, just using 'int' and 'string' as examples.
Dictionary<int, string> dict = new Dictionary<int, string>();

// Deconstructor gets called here.
foreach (var (key, value) in dict)
{
   Console.WriteLine($"{key} : {value}");
}
3 голосов
/ 28 июля 2016

Стандартный способ перебора словаря в соответствии с официальной документацией на MSDN:

foreach (DictionaryEntry entry in myDictionary)
{
     //Read entry.Key and entry.Value here
}
3 голосов
/ 02 октября 2014

Я воспользуюсь преимуществом .NET 4.0+ и предоставлю обновленный ответ на первоначально принятый:

foreach(var entry in MyDic)
{
    // do something with entry.Value or entry.Key
}
2 голосов
/ 09 декабря 2008

Если, скажем, вы хотите перебрать коллекцию значений по умолчанию, я полагаю, что вы можете реализовать IEnumerable <>, где T - это тип объекта значений в словаре, а "this" - это словарь.

public new IEnumerator<T> GetEnumerator()
{
   return this.Values.GetEnumerator();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...