инициализация - поиск по dictionary c#




Каков наилучший способ перебора словаря? (17)

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


В некоторых случаях вам может понадобиться счетчик, который может быть предоставлен путем реализации цикла. Для этого LINQ предоставляет ElementAt который позволяет:

for (int index = 0; index < dictionary.Count; index++) {
  var item = dictionary.ElementAt(index);
  var itemKey = item.Key;
  var itemValue = item.Value;
}

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

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

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

FYI, foreach не работает, если значение имеет тип объекта.


Если вы пытаетесь использовать общий словарь в C #, как если бы вы использовали ассоциативный массив на другом языке:

foreach(var item in myDictionary)
{
  foo(item.Key);
  bar(item.Value);
}

Или, если вам нужно только перебирать набор ключей, используйте

foreach(var item in myDictionary.Keys)
{
  foo(item);
}

И, наконец, если вас интересуют только значения:

foreach(var item in myDictionary.Values)
{
  foo(item);
}

(Обратите внимание, что ключевое слово var является дополнительной функцией C # 3.0 и выше, вы также можете использовать точный тип своих ключей / значений здесь)


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

public new IEnumerator<T> GetEnumerator()
{
   return this.Values.GetEnumerator();
}

Зависит от того, находитесь ли вы за клавишами или значениями ...

Из Dictionary(TKey, TValue) MSDN Dictionary(TKey, TValue) Описание класса:

// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
    Console.WriteLine("Key = {0}, Value = {1}", 
        kvp.Key, kvp.Value);
}

// To get the values alone, use the Values property.
Dictionary<string, string>.ValueCollection valueColl =
    openWith.Values;

// The elements of the ValueCollection are strongly typed
// with the type that was specified for dictionary values.
Console.WriteLine();
foreach( string s in valueColl )
{
    Console.WriteLine("Value = {0}", s);
}

// To get the keys alone, use the Keys property.
Dictionary<string, string>.KeyCollection keyColl =
    openWith.Keys;

// The elements of the KeyCollection are strongly typed
// with the type that was specified for dictionary keys.
Console.WriteLine();
foreach( string s in keyColl )
{
    Console.WriteLine("Key = {0}", s);
}

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

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


Как правило, просить «лучший способ» без конкретного контекста - это спрашивать, какой лучший цвет.

С одной стороны, есть много цветов, и лучшего цвета нет. Это зависит от необходимости и часто от вкуса.

С другой стороны, существует много способов перебора словаря на C #, и нет лучшего способа. Это зависит от необходимости и часто от вкуса.

Самый простой способ

foreach (var kvp in items)
{
    // key is kvp.Key
    doStuff(kvp.Value)
}

Если вам нужно только значение (позволяет называть его item , более читаемым, чем kvp.Value ).

foreach (var item in items.Values)
{
    doStuff(item)
}

Если вам нужен конкретный порядок сортировки

В общем, новички удивляются порядку перечисления Словаря.

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

foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
    // key is kvp.Key
    doStuff(kvp.Value)
}

Опять вам понадобится только значение. LINQ также обеспечивает краткое решение:

  • итерация непосредственно по значению (позволяет называть его item , более читаемым, чем kvp.Value )
  • но отсортированы по клавишам

Вот:

foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
    doStuff(item)
}

Из этих примеров можно сделать много примеров использования в реальном мире. Если вам не нужен конкретный заказ, просто придерживайтесь «самого простого пути» (см. Выше)!


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

foreach(var item in myDictionary)
{ 
    Console.WriteLine(item.Key);
    Console.WriteLine(item.Value);
}

С .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;
    }
}

С 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}");
}

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

foreach (DictionaryEntry entry in myDictionary)
{
     //Read entry.Key and entry.Value here
}

Я бы сказал, что foreach - стандартный способ, хотя он, очевидно, зависит от того, что вы ищете

foreach(var kvp in my_dictionary) {
  ...
}

Это то, что вы ищете?


Я написал расширение, чтобы перебрать словарь.

public static class DictionaryExtension
{
    public static void ForEach<T1, T2>(this Dictionary<T1, T2> dictionary, Action<T1, T2> action) {
        foreach(KeyValuePair<T1, T2> keyValue in dictionary) {
            action(keyValue.Key, keyValue.Value);
        }
    }
}

Затем вы можете позвонить

myDictionary.ForEach((x,y) => Console.WriteLine(x + " - " + y));

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

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

Это был единственный, с которым я смог нормально функционировать в классе, унаследованном от DictionaryBase.


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

foreach(KeyValuePair<string, string> entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}

или же

foreach(var entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}

наиболее полным является следующее, потому что вы можете видеть тип словаря из инициализации, kvp - KeyValuePair

var myDictionary = new Dictionary<string, string>(x);//fill dictionary with x

foreach(var kvp in myDictionary)//iterate over dictionary
{
    // do something with kvp.Value or kvp.Key
}

Словарь <TKey, TValue> Это общий класс коллекции в c #, и он хранит данные в формате значения ключа. Ключ должен быть уникальным и не может быть пустым, тогда как значение может быть дублирующимся и нулевым. Поскольку каждый элемент в словаре рассматривается как структура KeyValuePair <TKey, TValue>, представляющая ключ и его значение. и поэтому мы должны взять тип элемента KeyValuePair <TKey, TValue> во время итерации элемента. Ниже приведен пример.

Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");

foreach (KeyValuePair<int, string> item in dict)
{
    Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}

var dictionary = new Dictionary<string, int>
{
    { "Key", 12 }
};

var aggregateObjectCollection = dictionary.Select(
    entry => new AggregateObject(entry.Key, entry.Value));




loops