迭代字典的最佳方法是什么?

时间:2020-12-29 01:49:56

I've seen a few different ways to iterate over a dictionary in C#. Is there a standard way?

我已经看到了几种不同的方法来迭代C#中的字典。有标准的方法吗?

25 个解决方案

#1


2983  

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

#2


671  

If you are trying to use a generic Dictionary in C# like you would use an associative array in another language:

如果您尝试在C#中使用通用字典,则可以使用另一种语言的关联数组:

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

Or, if you only need to iterate over the collection of keys, use

或者,如果您只需要遍历密钥集合,请使用

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

And lastly, if you're only interested in the values:

最后,如果你只对价值感兴趣:

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

(Take note that the var keyword is an optional C# 3.0 and above feature, you could also use the exact type of your keys/values here)

(请注意,var关键字是可选的C#3.0及以上功能,您也可以在此处使用键/值的确切类型)

#3


111  

In some cases you may need a counter that may be provided by for-loop implementation. For that, LINQ provides ElementAt which enables the following:

在某些情况下,您可能需要一个可以通过for循环实现提供的计数器。为此,LINQ提供了ElementAt,它支持以下功能:

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

#4


75  

Depends on whether you're after the keys or the values...

取决于你是否在关键或价值观之后......

From the MSDN Dictionary(TKey, TValue) Class description:

来自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);}

#5


56  

Generally, asking for "the best way" without a specific context is like asking what is the best color.

一般来说,在没有特定背景的情况下询问“最好的方式”就像问什么是最好的颜色。

One the one hand, there are many colors and there's no best color. It depends on the need and often on taste, too.

一方面,有很多颜色,没有最好的颜色。这取决于需要,也经常取决于口味。

On the other hand, there are many ways to iterate over a Dictionary in C# and there's no best way. It depends on the need and often on taste, too.

另一方面,有许多方法可以在C#中迭代一个Dictionary而且没有最好的方法。这取决于需要,也经常取决于口味。

Most straightforward way

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

If you need only the value (allows to call it item, more readable than kvp.Value).

如果只需要值(允许调用它,比kvp.Value更可读)。

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

If you need a specific sort order

Generally, beginners are surprised about order of enumeration of a Dictionary.

通常,初学者对词典枚举的顺序感到惊讶。

LINQ provides a concise syntax that allows to specify order (and many other things), e.g.:

LINQ提供了一种简洁的语法,允许指定顺序(和许多其他东西),例如:

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

Again you might only need the value. LINQ also provides a concise solution to:

您可能只需要该值。 LINQ还提供简洁的解决方案:

  • iterate directly on the value (allows to call it item, more readable than kvp.Value)
  • 直接迭代值(允许调用它的项目,比kvp.Value更可读)

  • but sorted by the keys
  • 但按键排序

Here it is:

这里是:

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

There are many more real-world use case you can do from these examples.If you don't need a specific order, just stick to the "most straightforward way" (see above)!

您可以从这些示例中获得更多真实世界的用例。如果您不需要特定订单,只需坚持“最直接的方式”(见上文)!

#6


38  

I would say foreach is the standard way, though it obviously depends on what you're looking for

我会说foreach是标准的方式,虽然它显然取决于你在寻找什么

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

Is that what you're looking for?

这就是你要找的东西吗?

#7


29  

You can also try this on big dictionaries for multithreaded processing.

您也可以在大字典上尝试使用多线程处理。

dictionary.AsParallel().ForAll(pair => {     // Process pair.Key and pair.Value here});

#8


22  

There are plenty of options. My personal favorite is by KeyValuePair

有很多选择。我最喜欢的是KeyValuePair

Dictionary<string, object> myDictionary = new Dictionary<string, object>();// Populate your dictionary hereforeach (KeyValuePair<string,object> kvp in myDictionary){     // Do some interesting things}

You can also use the Keys and Values Collections

您还可以使用键和值集合

#9


22  

I appreciate this question has already had a lot of responses but I wanted to throw in a little research.

我很欣赏这个问题已经有了很多回复,但我想进行一些研究。

Iterating over a dictionary can be rather slow when compared with iterating over something like an array. In my tests an iteration over an array took 0.015003 seconds whereas an iteration over a dictionary (with the same number of elements) took 0.0365073 seconds that's 2.4 times as long! Although I have seen much bigger differences. For comparison a List was somewhere in between at 0.00215043 seconds.

与迭代类似数组的东西相比,迭代字典可能相当慢。在我的测试中,对数组的迭代花费了0.015003秒,而对字典的迭代(具有相同数量的元素)花费了0.0365073秒,这是2.4倍的长度!虽然我看到了更大的差异。为了比较,List介于0.00215043秒之间。

However, that is like comparing apples and oranges. My point is that iterating over dictionaries is slow.

然而,这就像比较苹果和橘子。我的观点是迭代字典很慢。

Dictionaries are optimised for lookups, so with that in mind I've created two methods. One simply does a foreach, the other iterates the keys then looks up.

字典针对查找进行了优化,因此考虑到这一点,我创建了两种方法。一个只是做一个foreach,另一个迭代键然后查找。

public static string Normal(Dictionary<string, string> dictionary){    string value;    int count = 0;    foreach (var kvp in dictionary)    {        value = kvp.Value;        count++;    }    return "Normal";}

This one loads the keys and iterates over them instead (I did also try pulling the keys into a string[] but the difference was negligible.

这个加载密钥并迭代它们(我也尝试将密钥拉成字符串[]但差别可以忽略不计。

public static string Keys(Dictionary<string, string> dictionary){    string value;    int count = 0;    foreach (var key in dictionary.Keys)    {        value = dictionary[key];        count++;    }    return "Keys";}

With this example the normal foreach test took 0.0310062 and the keys version took 0.2205441. Loading all the keys and iterating over all the lookups is clearly a LOT slower!

在这个例子中,正常的foreach测试花了0.0310062,密钥版本花了0.2205441。加载所有键并迭代所有查找显然要慢得多!

For a final test I've performed my iteration ten times to see if there are any benefits to using the keys here (by this point I was just curious):

对于最后的测试,我已经执行了十次迭代,看看在这里使用密钥是否有任何好处(此时我只是好奇):

Here's the RunTest method if that helps you visualise what's going on.

这是RunTest方法,如果这可以帮助您可视化正在发生的事情。

private static string RunTest<T>(T dictionary, Func<T, string> function){                DateTime start = DateTime.Now;    string name = null;    for (int i = 0; i < 10; i++)    {        name = function(dictionary);    }    DateTime end = DateTime.Now;    var duration = end.Subtract(start);    return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);}

Here the normal foreach run took 0.2820564 seconds (around ten times longer than a single iteration took - as you'd expect). The iteration over the keys took 2.2249449 seconds.

正常的foreach运行时间为0.2820564秒(大约是单次迭代的十倍 - 正如您所期望的那样)。密钥的迭代花了2.2249449秒。

Edited To Add:Reading some of the other answers made me question what would happen if I used Dictionary instead of Dictionary. In this example the array took 0.0120024 seconds, the list 0.0185037 seconds and the dictionary 0.0465093 seconds. It's reasonable to expect that the data type makes a difference on how much slower the dictionary is.

编辑添加:阅读其他一些答案让我怀疑如果我使用词典而不是词典将会发生什么。在此示例中,数组占用0.0120024秒,列表0.0185037秒,字典0.0465093秒。期望数据类型对字典的缓慢程度产生影响是合理的。

What are my Conclusions?

我的结论是什么?

  • Avoid iterating over a dictionary if you can, they are substantially slower than iterating over an array with the same data in it.
  • 如果可以的话,避免迭代字典,它们比在数组中使用相同数据进行迭代要慢得多。

  • If you do choose to iterate over a dictionary don't try to be too clever, although slower you could do a lot worse than using the standard foreach method.
  • 如果你确实选择迭代字典,不要试图太聪明,虽然速度比使用标准的foreach方法要差很多。

#10


9  

You suggested below to iterate

您建议在下面进行迭代

Dictionary<string,object> myDictionary = new Dictionary<string,object>();//Populate your dictionary hereforeach (KeyValuePair<string,object> kvp in myDictionary) {    //Do some interesting things;}

FYI, foreach doesn't work if the value are of type object.

仅供参考,如果值为object类型,则foreach不起作用。

#11


8  

With .NET Framework 4.7 one can use decomposition

使用.NET Framework 4.7,可以使用分解

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

To make this code work on lower C# versions, add System.ValueTuple NuGet package and write somewhere

要使此代码适用于较低的C#版本,请添加System.ValueTuple NuGet包并在某处写入

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

#12


7  

Simplest form to iterate a dictionary:

迭代字典的最简单形式:

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

#13


6  

Sometimes if you only needs the values to be enumerated, use the dictionary's value collection:

有时,如果您只需要枚举值,请使用字典的值集合:

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

Reported by this post which states it is the fastest method:http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html

本文报道称这是最快的方法:http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html

#14


5  

I found this method in the documentation for the DictionaryBase class on MSDN:

我在MSDN上的DictionaryBase类的文档中找到了这个方法:

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

This was the only one I was able to get functioning correctly in a class that inherited from the DictionaryBase.

这是我能够在从DictionaryBase继承的类中正确运行的唯一一个。

#15


5  

Using C# 7, add this extension method to any project of your solution:

使用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);    }}


And use this simple syntax

并使用这个简单的语法

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


Or this one, if you prefer

或者这个,如果你愿意的话

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


In place of the traditional

代替传统

foreach (KeyValuePair<string, object> kvp in dict){    string id = kvp.Key;    object value = kvp.Value;    // your code using 'id' and 'value'}


The extension method transforms the KeyValuePair of your IDictionary<TKey, TValue> into a strongly typed tuple, allowing you to use this new comfortable syntax.

扩展方法将IDictionary 的KeyValuePair转换为强类型元组,允许您使用这种新的舒适语法。 ,tvalue>

It converts -just- the required dictionary entries to tuples, so it does NOT converts the whole dictionary to tuples, so there are no performance concerns related to that.

它将-just-所需的字典条目转换为元组,因此它不会将整个字典转换为元组,因此没有与此相关的性能问题。

There is a only minor cost calling the extension method for creating a tuple in comparison with using the KeyValuePair directly, which should NOT be an issue if you are assigning the KeyValuePair's properties Key and Value to new loop variables anyway.

与直接使用KeyValuePair相比,调用创建元组的扩展方法只有一个小成本,如果您将KeyValuePair的属性Key和Value分配给新的循环变量,这不应该是一个问题。

In practice, this new syntax suits very well for most cases, except for low-level ultra-high performance scenarios, where you still have the option to simply not use it on that specific spot.

在实践中,这种新语法非常适合大多数情况,除了低级超高性能场景,您仍然可以选择不在特定位置使用它。

Check this out: MSDN Blog - New features in C# 7

看看这个:MSDN博客 - C#7中的新功能

#16


3  

I will take the advantage of .NET 4.0+ and provide an updated answer to the originally accepted one:

我将利用.NET 4.0+并提供最初接受的答案的更新答案:

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

#17


3  

The standard way to iterate over a Dictionary, according to official documentation on MSDN is:

根据MSDN上的官方文档,迭代字典的标准方法是:

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

#18


2  

If say, you want to iterate over the values collection by default, I believe you can implement IEnumerable<>, Where T is the type of the values object in the dictionary, and "this" is a Dictionary.

如果说,你想默认迭代值集合,我相信你可以实现IEnumerable <>,其中T是字典中值对象的类型,“this”是一个Dictionary。

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

#19


2  

As of C# 7, you can deconstruct objects into variables. I believe this to be the best way to iterate over a dictionary.

从C#7开始,您可以将对象解构为变量。我相信这是迭代字典的最佳方式。

Example:

Create an extension method on KeyValuePair<TKey, TVal> that deconstructs it:

在KeyValuePair 上创建一个解构它的扩展方法: ,tval>

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

Iterate over any Dictionary<TKey, TVal> in the following manner

以下列方式迭代任何Dictionary ,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}");}

#20


1  

var dictionary = new Dictionary<string, int>{    { "Key", 12 }};var aggregateObjectCollection = dictionary.Select(    entry => new AggregateObject(entry.Key, entry.Value));

#21


1  

Just wanted to add my 2 cent, as the most answers relate to foreach-loop.Please, take a look at the following code:

只想添加我的2美分,因为大多数答案与foreach-loop有关。请看下面的代码:

Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();//Add some entries to the dictionarymyProductPrices.ToList().ForEach(kvP => {    kvP.Value *= 1.15;    Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value));});

Altought this adds a additional call of '.ToList()', there might be a slight performance-improvement (as pointed out here foreach vs someList.Foreach(){}), espacially when working with large Dictionaries and running in parallel is no option / won't have an effect at all.

Altought这又增加了一个'.ToList()'调用,可能会有一点性能提升(正如foreach vs someList.Foreach(){}所指出的那样),特别是当使用大型字典并且并行运行时没有选项/根本没有效果。

Also, please note that you wont be able to assign values to the 'Value' property inside a foreach-loop. On the other hand, you will be able to manipulate the 'Key' as well, possibly getting you into trouble at runtime.

另外,请注意,您无法为foreach循环中的“Value”属性赋值。另一方面,您也可以操纵'Key',可能会让您在运行时遇到麻烦。

When you just want to "read" Keys and Values, you might also use IEnumerable.Select().

当您只想“读取”键和值时,您也可以使用IEnumerable.Select()。

var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );

#22


1  

I wrote an extension to loop over a 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);        }    }}

Then you can call

然后你可以打电话

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

#23


0  

Dictionary< TKey, TValue > It is a generic collection class in c# and it stores the data in the key value format.Key must be unique and it can not be null whereas value can be duplicate and null.As each item in the dictionary is treated as KeyValuePair< TKey, TValue > structure representing a key and its value. and hence we should take the element type KeyValuePair< TKey, TValue> during the iteration of element.Below is the example.

Dictionary 它是c#中的泛型集合类,它以键值格式存储数据.Key必须是唯一的,它不能为null,而值可以是重复的和null。因为字典中的每个项目都是被视为KeyValuePair 表示密钥及其值的结构。因此我们应该在元素的迭代过程中采用元素类型KeyValuePair .Below就是一个例子。 ,tvalue> ,tvalue> ,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);}

#24


-1  

in addition to the highest ranking posts where there is a discussion between using

除了排名最高的帖子之外,还有使用过程之间的讨论

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

or

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

most complete is the following because you can see the dictionary type from the initialization, kvp is KeyValuePair

最完整的是以下因为你可以从初始化看到字典类型,kvp是KeyValuePair

var myDictionary = new Dictionary<string, string>(x);//fill dictionary with xforeach(var kvp in myDictionary)//iterate over dictionary{    // do something with kvp.Value or kvp.Key}

#25


-2  

Dictionaries are special lists, whereas every value in the list has a key which is also a variable. A good example of a dictionary is a phone book.

字典是特殊列表,而列表中的每个值都有一个键,它也是一个变量。字典的一个很好的例子是电话簿。

   Dictionary<string, long> phonebook = new Dictionary<string, long>();    phonebook.Add("Alex", 4154346543);    phonebook["Jessica"] = 4159484588;

Notice that when defining a dictionary, we need to provide a generic definition with two types - the type of the key and the type of the value. In this case, the key is a string whereas the value is an integer.

请注意,在定义字典时,我们需要提供两种类型的泛型定义 - 键的类型和值的类型。在这种情况下,键是一个字符串,而值是一个整数。

There are also two ways of adding a single value to the dictionary, either using the brackets operator or using the Add method.

还有两种方法可以使用括号运算符或使用Add方法向字典添加单个值。

To check whether a dictionary has a certain key in it, we can use the ContainsKey method:

要检查字典中是否有某个键,我们可以使用ContainsKey方法:

Dictionary<string, long> phonebook = new Dictionary<string, long>();phonebook.Add("Alex", 415434543);phonebook["Jessica"] = 415984588;if (phonebook.ContainsKey("Alex")){    Console.WriteLine("Alex's number is " + phonebook["Alex"]);}

To remove an item from a dictionary, we can use the Remove method. Removing an item from a dictionary by its key is fast and very efficient. When removing an item from a List using its value, the process is slow and inefficient, unlike the dictionary Remove function.

要从字典中删除项目,我们可以使用Remove方法。通过键从字典中删除项目非常快速且非常高效。使用其值从List中删除项目时,该过程缓慢且效率低,与字典“删除”功能不同。

Dictionary<string, long> phonebook = new Dictionary<string, long>();phonebook.Add("Alex", 415434543);phonebook["Jessica"] = 415984588;phonebook.Remove("Jessica");Console.WriteLine(phonebook.Count);

#1


2983  

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

#2


671  

If you are trying to use a generic Dictionary in C# like you would use an associative array in another language:

如果您尝试在C#中使用通用字典,则可以使用另一种语言的关联数组:

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

Or, if you only need to iterate over the collection of keys, use

或者,如果您只需要遍历密钥集合,请使用

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

And lastly, if you're only interested in the values:

最后,如果你只对价值感兴趣:

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

(Take note that the var keyword is an optional C# 3.0 and above feature, you could also use the exact type of your keys/values here)

(请注意,var关键字是可选的C#3.0及以上功能,您也可以在此处使用键/值的确切类型)

#3


111  

In some cases you may need a counter that may be provided by for-loop implementation. For that, LINQ provides ElementAt which enables the following:

在某些情况下,您可能需要一个可以通过for循环实现提供的计数器。为此,LINQ提供了ElementAt,它支持以下功能:

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

#4


75  

Depends on whether you're after the keys or the values...

取决于你是否在关键或价值观之后......

From the MSDN Dictionary(TKey, TValue) Class description:

来自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);}

#5


56  

Generally, asking for "the best way" without a specific context is like asking what is the best color.

一般来说,在没有特定背景的情况下询问“最好的方式”就像问什么是最好的颜色。

One the one hand, there are many colors and there's no best color. It depends on the need and often on taste, too.

一方面,有很多颜色,没有最好的颜色。这取决于需要,也经常取决于口味。

On the other hand, there are many ways to iterate over a Dictionary in C# and there's no best way. It depends on the need and often on taste, too.

另一方面,有许多方法可以在C#中迭代一个Dictionary而且没有最好的方法。这取决于需要,也经常取决于口味。

Most straightforward way

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

If you need only the value (allows to call it item, more readable than kvp.Value).

如果只需要值(允许调用它,比kvp.Value更可读)。

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

If you need a specific sort order

Generally, beginners are surprised about order of enumeration of a Dictionary.

通常,初学者对词典枚举的顺序感到惊讶。

LINQ provides a concise syntax that allows to specify order (and many other things), e.g.:

LINQ提供了一种简洁的语法,允许指定顺序(和许多其他东西),例如:

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

Again you might only need the value. LINQ also provides a concise solution to:

您可能只需要该值。 LINQ还提供简洁的解决方案:

  • iterate directly on the value (allows to call it item, more readable than kvp.Value)
  • 直接迭代值(允许调用它的项目,比kvp.Value更可读)

  • but sorted by the keys
  • 但按键排序

Here it is:

这里是:

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

There are many more real-world use case you can do from these examples.If you don't need a specific order, just stick to the "most straightforward way" (see above)!

您可以从这些示例中获得更多真实世界的用例。如果您不需要特定订单,只需坚持“最直接的方式”(见上文)!

#6


38  

I would say foreach is the standard way, though it obviously depends on what you're looking for

我会说foreach是标准的方式,虽然它显然取决于你在寻找什么

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

Is that what you're looking for?

这就是你要找的东西吗?

#7


29  

You can also try this on big dictionaries for multithreaded processing.

您也可以在大字典上尝试使用多线程处理。

dictionary.AsParallel().ForAll(pair => {     // Process pair.Key and pair.Value here});

#8


22  

There are plenty of options. My personal favorite is by KeyValuePair

有很多选择。我最喜欢的是KeyValuePair

Dictionary<string, object> myDictionary = new Dictionary<string, object>();// Populate your dictionary hereforeach (KeyValuePair<string,object> kvp in myDictionary){     // Do some interesting things}

You can also use the Keys and Values Collections

您还可以使用键和值集合

#9


22  

I appreciate this question has already had a lot of responses but I wanted to throw in a little research.

我很欣赏这个问题已经有了很多回复,但我想进行一些研究。

Iterating over a dictionary can be rather slow when compared with iterating over something like an array. In my tests an iteration over an array took 0.015003 seconds whereas an iteration over a dictionary (with the same number of elements) took 0.0365073 seconds that's 2.4 times as long! Although I have seen much bigger differences. For comparison a List was somewhere in between at 0.00215043 seconds.

与迭代类似数组的东西相比,迭代字典可能相当慢。在我的测试中,对数组的迭代花费了0.015003秒,而对字典的迭代(具有相同数量的元素)花费了0.0365073秒,这是2.4倍的长度!虽然我看到了更大的差异。为了比较,List介于0.00215043秒之间。

However, that is like comparing apples and oranges. My point is that iterating over dictionaries is slow.

然而,这就像比较苹果和橘子。我的观点是迭代字典很慢。

Dictionaries are optimised for lookups, so with that in mind I've created two methods. One simply does a foreach, the other iterates the keys then looks up.

字典针对查找进行了优化,因此考虑到这一点,我创建了两种方法。一个只是做一个foreach,另一个迭代键然后查找。

public static string Normal(Dictionary<string, string> dictionary){    string value;    int count = 0;    foreach (var kvp in dictionary)    {        value = kvp.Value;        count++;    }    return "Normal";}

This one loads the keys and iterates over them instead (I did also try pulling the keys into a string[] but the difference was negligible.

这个加载密钥并迭代它们(我也尝试将密钥拉成字符串[]但差别可以忽略不计。

public static string Keys(Dictionary<string, string> dictionary){    string value;    int count = 0;    foreach (var key in dictionary.Keys)    {        value = dictionary[key];        count++;    }    return "Keys";}

With this example the normal foreach test took 0.0310062 and the keys version took 0.2205441. Loading all the keys and iterating over all the lookups is clearly a LOT slower!

在这个例子中,正常的foreach测试花了0.0310062,密钥版本花了0.2205441。加载所有键并迭代所有查找显然要慢得多!

For a final test I've performed my iteration ten times to see if there are any benefits to using the keys here (by this point I was just curious):

对于最后的测试,我已经执行了十次迭代,看看在这里使用密钥是否有任何好处(此时我只是好奇):

Here's the RunTest method if that helps you visualise what's going on.

这是RunTest方法,如果这可以帮助您可视化正在发生的事情。

private static string RunTest<T>(T dictionary, Func<T, string> function){                DateTime start = DateTime.Now;    string name = null;    for (int i = 0; i < 10; i++)    {        name = function(dictionary);    }    DateTime end = DateTime.Now;    var duration = end.Subtract(start);    return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);}

Here the normal foreach run took 0.2820564 seconds (around ten times longer than a single iteration took - as you'd expect). The iteration over the keys took 2.2249449 seconds.

正常的foreach运行时间为0.2820564秒(大约是单次迭代的十倍 - 正如您所期望的那样)。密钥的迭代花了2.2249449秒。

Edited To Add:Reading some of the other answers made me question what would happen if I used Dictionary instead of Dictionary. In this example the array took 0.0120024 seconds, the list 0.0185037 seconds and the dictionary 0.0465093 seconds. It's reasonable to expect that the data type makes a difference on how much slower the dictionary is.

编辑添加:阅读其他一些答案让我怀疑如果我使用词典而不是词典将会发生什么。在此示例中,数组占用0.0120024秒,列表0.0185037秒,字典0.0465093秒。期望数据类型对字典的缓慢程度产生影响是合理的。

What are my Conclusions?

我的结论是什么?

  • Avoid iterating over a dictionary if you can, they are substantially slower than iterating over an array with the same data in it.
  • 如果可以的话,避免迭代字典,它们比在数组中使用相同数据进行迭代要慢得多。

  • If you do choose to iterate over a dictionary don't try to be too clever, although slower you could do a lot worse than using the standard foreach method.
  • 如果你确实选择迭代字典,不要试图太聪明,虽然速度比使用标准的foreach方法要差很多。

#10


9  

You suggested below to iterate

您建议在下面进行迭代

Dictionary<string,object> myDictionary = new Dictionary<string,object>();//Populate your dictionary hereforeach (KeyValuePair<string,object> kvp in myDictionary) {    //Do some interesting things;}

FYI, foreach doesn't work if the value are of type object.

仅供参考,如果值为object类型,则foreach不起作用。

#11


8  

With .NET Framework 4.7 one can use decomposition

使用.NET Framework 4.7,可以使用分解

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

To make this code work on lower C# versions, add System.ValueTuple NuGet package and write somewhere

要使此代码适用于较低的C#版本,请添加System.ValueTuple NuGet包并在某处写入

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

#12


7  

Simplest form to iterate a dictionary:

迭代字典的最简单形式:

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

#13


6  

Sometimes if you only needs the values to be enumerated, use the dictionary's value collection:

有时,如果您只需要枚举值,请使用字典的值集合:

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

Reported by this post which states it is the fastest method:http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html

本文报道称这是最快的方法:http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html

#14


5  

I found this method in the documentation for the DictionaryBase class on MSDN:

我在MSDN上的DictionaryBase类的文档中找到了这个方法:

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

This was the only one I was able to get functioning correctly in a class that inherited from the DictionaryBase.

这是我能够在从DictionaryBase继承的类中正确运行的唯一一个。

#15


5  

Using C# 7, add this extension method to any project of your solution:

使用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);    }}


And use this simple syntax

并使用这个简单的语法

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


Or this one, if you prefer

或者这个,如果你愿意的话

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


In place of the traditional

代替传统

foreach (KeyValuePair<string, object> kvp in dict){    string id = kvp.Key;    object value = kvp.Value;    // your code using 'id' and 'value'}


The extension method transforms the KeyValuePair of your IDictionary<TKey, TValue> into a strongly typed tuple, allowing you to use this new comfortable syntax.

扩展方法将IDictionary 的KeyValuePair转换为强类型元组,允许您使用这种新的舒适语法。 ,tvalue>

It converts -just- the required dictionary entries to tuples, so it does NOT converts the whole dictionary to tuples, so there are no performance concerns related to that.

它将-just-所需的字典条目转换为元组,因此它不会将整个字典转换为元组,因此没有与此相关的性能问题。

There is a only minor cost calling the extension method for creating a tuple in comparison with using the KeyValuePair directly, which should NOT be an issue if you are assigning the KeyValuePair's properties Key and Value to new loop variables anyway.

与直接使用KeyValuePair相比,调用创建元组的扩展方法只有一个小成本,如果您将KeyValuePair的属性Key和Value分配给新的循环变量,这不应该是一个问题。

In practice, this new syntax suits very well for most cases, except for low-level ultra-high performance scenarios, where you still have the option to simply not use it on that specific spot.

在实践中,这种新语法非常适合大多数情况,除了低级超高性能场景,您仍然可以选择不在特定位置使用它。

Check this out: MSDN Blog - New features in C# 7

看看这个:MSDN博客 - C#7中的新功能

#16


3  

I will take the advantage of .NET 4.0+ and provide an updated answer to the originally accepted one:

我将利用.NET 4.0+并提供最初接受的答案的更新答案:

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

#17


3  

The standard way to iterate over a Dictionary, according to official documentation on MSDN is:

根据MSDN上的官方文档,迭代字典的标准方法是:

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

#18


2  

If say, you want to iterate over the values collection by default, I believe you can implement IEnumerable<>, Where T is the type of the values object in the dictionary, and "this" is a Dictionary.

如果说,你想默认迭代值集合,我相信你可以实现IEnumerable <>,其中T是字典中值对象的类型,“this”是一个Dictionary。

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

#19


2  

As of C# 7, you can deconstruct objects into variables. I believe this to be the best way to iterate over a dictionary.

从C#7开始,您可以将对象解构为变量。我相信这是迭代字典的最佳方式。

Example:

Create an extension method on KeyValuePair<TKey, TVal> that deconstructs it:

在KeyValuePair 上创建一个解构它的扩展方法: ,tval>

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

Iterate over any Dictionary<TKey, TVal> in the following manner

以下列方式迭代任何Dictionary ,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}");}

#20


1  

var dictionary = new Dictionary<string, int>{    { "Key", 12 }};var aggregateObjectCollection = dictionary.Select(    entry => new AggregateObject(entry.Key, entry.Value));

#21


1  

Just wanted to add my 2 cent, as the most answers relate to foreach-loop.Please, take a look at the following code:

只想添加我的2美分,因为大多数答案与foreach-loop有关。请看下面的代码:

Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();//Add some entries to the dictionarymyProductPrices.ToList().ForEach(kvP => {    kvP.Value *= 1.15;    Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value));});

Altought this adds a additional call of '.ToList()', there might be a slight performance-improvement (as pointed out here foreach vs someList.Foreach(){}), espacially when working with large Dictionaries and running in parallel is no option / won't have an effect at all.

Altought这又增加了一个'.ToList()'调用,可能会有一点性能提升(正如foreach vs someList.Foreach(){}所指出的那样),特别是当使用大型字典并且并行运行时没有选项/根本没有效果。

Also, please note that you wont be able to assign values to the 'Value' property inside a foreach-loop. On the other hand, you will be able to manipulate the 'Key' as well, possibly getting you into trouble at runtime.

另外,请注意,您无法为foreach循环中的“Value”属性赋值。另一方面,您也可以操纵'Key',可能会让您在运行时遇到麻烦。

When you just want to "read" Keys and Values, you might also use IEnumerable.Select().

当您只想“读取”键和值时,您也可以使用IEnumerable.Select()。

var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );

#22


1  

I wrote an extension to loop over a 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);        }    }}

Then you can call

然后你可以打电话

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

#23


0  

Dictionary< TKey, TValue > It is a generic collection class in c# and it stores the data in the key value format.Key must be unique and it can not be null whereas value can be duplicate and null.As each item in the dictionary is treated as KeyValuePair< TKey, TValue > structure representing a key and its value. and hence we should take the element type KeyValuePair< TKey, TValue> during the iteration of element.Below is the example.

Dictionary 它是c#中的泛型集合类,它以键值格式存储数据.Key必须是唯一的,它不能为null,而值可以是重复的和null。因为字典中的每个项目都是被视为KeyValuePair 表示密钥及其值的结构。因此我们应该在元素的迭代过程中采用元素类型KeyValuePair .Below就是一个例子。 ,tvalue> ,tvalue> ,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);}

#24


-1  

in addition to the highest ranking posts where there is a discussion between using

除了排名最高的帖子之外,还有使用过程之间的讨论

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

or

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

most complete is the following because you can see the dictionary type from the initialization, kvp is KeyValuePair

最完整的是以下因为你可以从初始化看到字典类型,kvp是KeyValuePair

var myDictionary = new Dictionary<string, string>(x);//fill dictionary with xforeach(var kvp in myDictionary)//iterate over dictionary{    // do something with kvp.Value or kvp.Key}

#25


-2  

Dictionaries are special lists, whereas every value in the list has a key which is also a variable. A good example of a dictionary is a phone book.

字典是特殊列表,而列表中的每个值都有一个键,它也是一个变量。字典的一个很好的例子是电话簿。

   Dictionary<string, long> phonebook = new Dictionary<string, long>();    phonebook.Add("Alex", 4154346543);    phonebook["Jessica"] = 4159484588;

Notice that when defining a dictionary, we need to provide a generic definition with two types - the type of the key and the type of the value. In this case, the key is a string whereas the value is an integer.

请注意,在定义字典时,我们需要提供两种类型的泛型定义 - 键的类型和值的类型。在这种情况下,键是一个字符串,而值是一个整数。

There are also two ways of adding a single value to the dictionary, either using the brackets operator or using the Add method.

还有两种方法可以使用括号运算符或使用Add方法向字典添加单个值。

To check whether a dictionary has a certain key in it, we can use the ContainsKey method:

要检查字典中是否有某个键,我们可以使用ContainsKey方法:

Dictionary<string, long> phonebook = new Dictionary<string, long>();phonebook.Add("Alex", 415434543);phonebook["Jessica"] = 415984588;if (phonebook.ContainsKey("Alex")){    Console.WriteLine("Alex's number is " + phonebook["Alex"]);}

To remove an item from a dictionary, we can use the Remove method. Removing an item from a dictionary by its key is fast and very efficient. When removing an item from a List using its value, the process is slow and inefficient, unlike the dictionary Remove function.

要从字典中删除项目,我们可以使用Remove方法。通过键从字典中删除项目非常快速且非常高效。使用其值从List中删除项目时,该过程缓慢且效率低,与字典“删除”功能不同。

Dictionary<string, long> phonebook = new Dictionary<string, long>();phonebook.Add("Alex", 415434543);phonebook["Jessica"] = 415984588;phonebook.Remove("Jessica");Console.WriteLine(phonebook.Count);