I've seen a few different ways to iterate over a dictionary in C#. Is there a standard way?
-
90@VikasGupta What would you suggest for doing something with a collection of key-value pairs when you don't know what the keys are going to be? – nasch Feb 26 '15 at 22:27
-
10@nasch: `myDictionary.Keys` will give you a collection containing the keys in `myDictionary`. – displayName Oct 28 '15 at 13:47
-
33@displayName If you want to do something with each key-value pair but don't have a reference to the keys to use to look up values, you would iterate over the dictionary, right? I was just pointing out that there could be times you would want to do that, despite Vikas' claim that this is usually incorrect usage. – nasch Oct 28 '15 at 18:01
-
46To say that it's incorrect usage implies that there's a better alternative. What's that alternative? – Kyle Delaney Jun 20 '17 at 21:13
-
69VikasGupta is wrong, I can affirm that after many years of high-performance C# and C++ programming in non-theoretical scenarios. There are indeed frequent cases where one would create a dictionary, store unique key-value pairs, and then iterate over these values, which are proven to have unique keys within the collection. Creating any further collections is a really inefficient and costly way of avoiding dictionary iteration. Please provide a good alternative as answer to the question clarifying your point of view, otherwise your comment is pretty nonsensical. – sɐunıɔןɐqɐp Aug 01 '18 at 20:53
-
3Also for debugging and trying to figure out whats in your dictionary when something goes wrong. This is very helpful – MingMan Sep 10 '18 at 16:30
-
13VikasGupta is 100% correct. If you have "_a collection of key-value pairs_" and don't know what to do with it, you can _literally_ put it into an `ICollection
` (easiest implementation: `List`). And if you're concerned with "_high-performance programming_", then you should be aware that **the only thing Dictionaries are faster at is looking up an item via key** - adding items is slower and [iterating over a dictionary can easily take twice as long as iterating over a list](https://chrisvall.com/coding/c-dictionary-benchmark-testing-getting-allone-values). – Raphael Schmitz Mar 12 '19 at 16:53 -
There are three other ways to do this: 1- for Loop 2- Parallel Enumerable.ForAllMethod 3- String.Join You can see a sample of their code in this link: https://www.techiedelight.com/iterate-over-dictionary-csharp/ – elnaz jangi Jun 12 '20 at 13:16
-
1I guess converting a Dictionary to a List (even using LINQ) requires iterating. Or what if you need to call a method for each item in the dictionary ? – Mauricio Gracia Gutierrez Jun 10 '21 at 15:02
-
@MateenUlhaq I think that you've shortened the question too much. Now ([5th revision](https://stackoverflow.com/revisions/141088/5)) it's almost a paraphrasing of the title, without any additional context. I am voting to revert to the previous version. – Theodor Zoulias May 08 '22 at 18:06
-
1@TheodorZoulias The context is probably not needed for the question to function since "What is the best way / standard" questions are usually considered off-topic, but I've reverted it. – Mateen Ulhaq May 08 '22 at 18:17
29 Answers
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
- 3,160
- 1
- 18
- 36
- 98,892
- 55
- 184
- 226
-
1This is nice, but is there any concise syntax to unpack the key and value into their own variables from a KeyValuePair? E.g. in Python if I knew my keys were people's names and my values addresses, I might write `for (name, address) in myDictionary.items()` – user2428107 Mar 18 '22 at 03:23
-
7@user2428107 You can use deconstruction in c# to accomplish this. `foreach (var (key, value) in myDictionary)` – dimension314 Mar 25 '22 at 17:43
If you are trying to use a generic Dictionary in C# like you would use an associative array in another language:
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)
- 21,915
- 7
- 38
- 55
-
43I appreciate that this answer points out you can iterate over the keys or the values explicitly. – Rotsiser Mho Jan 13 '15 at 06:17
-
11`var` should be used sparingly, in my opinion. Particularly here, it is not constructive: the type `KeyValuePair` is likely relevant to the question. – Sinjai Aug 21 '17 at 16:21
-
4`var` has a unique purpose and i don't believe it is 'syntactic' sugar. Using it purposefully is an appropriate approach. – Joshua K Sep 07 '18 at 18:43
-
1using var in a foreach statement is dangerous because sometimes the compiler replace "var" with "object" instead of using the proper type. – Maxter Dec 03 '19 at 16:56
-
1@JamesWierzba I would say what hurts readability is the lack of a good variable name (due to it being a demo example). In real code, had it been `foreach (var vehicle in line.Values) { start(vehicle); }` it would be readable just fine. – spectras Jun 11 '20 at 11:53
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 (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
- 2,875
- 2
- 31
- 38
- 2,525
- 1
- 13
- 2
-
22To use the '.ElementAt' method, remember: using System.Linq; This is not incluted in fx. auto generated test classes. – Tinia Nov 24 '11 at 14:47
-
14This is the way to go if you are modifying the values associated with the keys. Otherwise an exception is thrown when modifying and using foreach(). – Mike de Klerk Apr 03 '13 at 07:18
-
This is useful when you want to modify while iterate.The `foreach` version will throw exception while you enumerate the collection. – zionpi Jan 21 '15 at 09:03
-
38
-
188This answer is completely undeserving of so many upvotes. A dictionary has no implicit order, so using `.ElementAt` in this context might lead to subtle bugs. Far more serious is Arturo's point above. You'll be iterating the dictionary `dictionary.Count + 1` times leading to O(n^2) complexity for an operation that should only be O(n). If you really need an index (if you do, you're probably using the wrong collection type in the first place), you should iterate `dictionary.Select( (kvp, idx) => new {Index = idx, kvp.Key, kvp.Value})` instead and not use `.ElementAt` inside the loop. – spender Mar 02 '15 at 02:17
-
3
-
1@MikedeKlerk, modifying the dictionary while iterating it is not safe. See the comments under http://stackoverflow.com/a/31112746/24315. – Neil Feb 09 '16 at 00:03
-
12ElementAt - o(n) operation! Seriously? This is the example of how you should not do it. These many upvotes? – Mukesh Adhvaryu May 12 '16 at 22:14
-
@spender Agree. Of course, an alternative is `var dictCopy = dictionary.ToArray();` (again using a Linq extension), and the you can access `dictCopy` by array index afterwards. – Jeppe Stig Nielsen Jun 05 '16 at 15:21
-
3
-
3In [my answer](https://stackoverflow.com/a/61511704/150605) to [Looping for vs foreach difference in iterating dictionary c#](https://stackoverflow.com/q/61507883/150605) I compared several methods of iterating a `Dictionary<>`. In addition to finding that `foreach`/`GetEnumerator()` is the fastest way to do so, I found that **`ElementAt()` is a terrible way to do this**. For a 10-element dictionary `ElementAt()` is **~8x slower**, and for 1,000 elements that grows to **~400x slower**. Among the other suggestions, consider simply declaring an index variable outside of a `foreach` loop. – Lance U. Matthews Apr 30 '20 at 01:58
Depends on whether you're after the keys or the values...
From the MSDN Dictionary(TKey, TValue) Class description:
// 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);
}
- 2,272
- 1
- 18
- 13
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.
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).
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.:
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:
- iterate directly on the value (allows to call it
item, more readable thankvp.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,544
- 5
- 53
- 87
- 5,577
- 3
- 33
- 48
-
-
@Mafii Are you sure? Values returned by OrderBy are not of a KeyValuePair type, they have no `Value` field. Exact type I see here is `IOrderedEnumerable
>`. Perhaps you meant something else? Can you write a complete line showing what you mean (and test it)? – Stéphane Gourichon Sep 23 '16 at 14:30 -
I think this answer contains what I mean: http://stackoverflow.com/a/141105/5962841 but correct me if I confused something – Mafii Sep 23 '16 at 14:34
-
No, read the end. There is a .Keys and a .Values property. No need to query with select... – Mafii Sep 23 '16 at 15:07
-
1@Mafii Re-read my whole answer, explanations between code sections tell the context. The answer you mention is like second code section in my answer (no order required). There I just wrote `items.Value` like you suggested. In the case of the fourth section that you commented, the `Select()` is a way to cause `foreach` to enumerate directly on the values in the dictionary instead of key-value pairs. If somehow you don't like the `Select()` in this case, you might prefer the third code section. The point of the fourth section is to show that one can pre-process the collection with LINQ. – Stéphane Gourichon Sep 23 '16 at 15:14
-
-
1If you do `.Keys.Orderby()` you'll iterate on a list of keys. If that's all you need, fine. If you need values, then in the loop you'd have to query the dictionary on each key to get the value. In many scenarios it won't make a practical difference. In high-performance scenario, it will. Like I wrote in the beginning of the answer: "there are many ways (...) and there's no best way. It depends on the need and often on taste, too." – Stéphane Gourichon Sep 23 '16 at 15:23
-
Well, you could also .Values.Orderby. just my 5 Cents ;) i agree tho, it doesnt really matter. – Mafii Sep 23 '16 at 15:24
-
Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/124056/discussion-between-stephane-gourichon-and-mafii). – Stéphane Gourichon Sep 23 '16 at 15:32
I would say foreach is the standard way, though it obviously depends on what you're looking for
foreach(var kvp in my_dictionary) {
...
}
Is that what you're looking for?
- 5,738
- 3
- 33
- 41
- 110,852
- 124
- 360
- 595
C# 7.0 introduced Deconstructors and if you are using .NET Core 2.0+ Application, the struct KeyValuePair<> already include a Deconstruct() for you. So you can do:
var dic = new Dictionary<int, string>() { { 1, "One" }, { 2, "Two" }, { 3, "Three" } };
foreach (var (key, value) in dic) {
Console.WriteLine($"Item [{key}] = {value}");
}
//Or
foreach (var (_, value) in dic) {
Console.WriteLine($"Item [NO_ID] = {value}");
}
//Or
foreach ((int key, string value) in dic) {
Console.WriteLine($"Item [{key}] = {value}");
}
- 13,276
- 5
- 70
- 79
-
10If your using .NET Framework, which at least upto 4.7.2 does not have the Deconstruct on the KeyValuePair, try this: `foreach (var (key, value) in dic.Select(x => (x.Key, x.Value)))` – nwsmith Apr 26 '19 at 11:58
You can also try this on big dictionaries for multithreaded processing.
dictionary
.AsParallel()
.ForAll(pair =>
{
// Process pair.Key and pair.Value here
});
- 812
- 9
- 18
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.
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.
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!
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.
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.
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.
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.
-
12You should measure with something like StopWatch instead of DateTime: http://www.hanselman.com/blog/ProperBenchmarkingToDiagnoseAndSolveANETSerializationBottleneck.aspx – Even Mien Feb 23 '15 at 19:26
-
3could you please describe your test scenario, how many items where in your dictionary, how often did you run your scenario to calculate the average time, ... – WiiMaxx Jul 29 '15 at 08:57
-
4Interestingly you will get different results depending upon what data you have in the dictionary. While itterating over the Dictionary the Enumerator function has to skip a lot of empty slots in the dictionary which is what causes it to be slower than iterating over an array. If the Dictionary is full up there will be less empty slots to skip than if it is half empty. – Martin Brown Jun 30 '16 at 08:36
As already pointed out on this answer, KeyValuePair<TKey, TValue> implements a Deconstruct method starting on .NET Core 2.0, .NET Standard 2.1 and .NET Framework 5.0 (preview).
With this, it's possible to iterate through a dictionary in a KeyValuePair agnostic way:
var dictionary = new Dictionary<int, string>();
// ...
foreach (var (key, value) in dictionary)
{
// ...
}
- 843
- 1
- 9
- 16
There are plenty of options. My personal favorite is by KeyValuePair
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary)
{
// Do some interesting things
}
You can also use the Keys and Values Collections
-
Upvoting this one.. and appreciate the NON use of "var". I hate code samples with "var" in them. Unless it is "var emp = new Employee()"...one has no/little idea what the var is. Thanks. – granadaCoder Jul 24 '20 at 15:05
-
1@granadaCoder if no one can tell what `var` is then you're not doing naming correctly – Eonasdan Sep 14 '20 at 14:21
With .NET Framework 4.7 one can use decomposition
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
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;
}
}
- 4,389
- 4
- 25
- 45
-
11This is incorrect. .NET 4.7 simply has `ValueTuple` built in. It's available as a nuget package for earlier versions. More importantly, C# 7.0+ is needed for the `Deconstruct` method to work as a deconstructor for `var (fruit, number) in fruits`. – David Arno Oct 18 '17 at 11:58
- 866
- 1
- 9
- 20
-
2Why are you calling `ContainsKey()` in the `for` version? That adds extra overhead that's not present in the code you're comparing against. [`TryGetValue()`](https://docs.microsoft.com/dotnet/api/system.collections.generic.idictionary-2.trygetvalue) exists to replace that exact "if key exists, get item with key" pattern. Further, if `dict` contains a contiguous range of integers from `0` to `dictCount - 1`, you know the indexer can't fail; otherwise, `dict.Keys` is what you should be iterating. Either way, no `ContainsKey()`/`TryGetValue()` needed. Last, please don't post screenshots of code. – Lance U. Matthews Apr 29 '20 at 18:55
As of C# 7, you can deconstruct objects into variables. I believe this to be the best way to iterate over a dictionary.
Example:
Create an extension method on KeyValuePair<TKey, TVal> that deconstructs it:
public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey key, out TVal value)
{
key = pair.Key;
value = pair.Value;
}
Iterate over any Dictionary<TKey, TVal> in the following manner
// 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}");
}
- 580
- 10
- 28
- 492
- 2
- 10
- 19
Simplest form to iterate a dictionary:
foreach(var item in myDictionary)
{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}
- 817
- 8
- 14
- 1,779
- 4
- 17
- 34
Using C# 7, add this extension method to any project of your solution:
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.
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.
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.
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
- 2,877
- 15
- 33
- 38
-
1What would be the reason to prefer 'comfortable' tuples to key-value-pair's? I don't see a gain here. Your tuple contains a key and a value, so does the key-value-pair. – Maarten Sep 10 '18 at 12:57
-
6Hi Maarten, thanks for your question. The main benefit is code readability without additional programming effort. With KeyValuePair one must always use the form `kvp.Key` and `kvp.Value` for using respectively key and value. With tuples you get the flexibility to name the key and the value as you wish, without using further variable declarations inside the foreach block. E.g. you may name your key as `factoryName`, and the value as `models`, which is especially useful when you get nested loops (dictionaries of dictionaries): code maintenance gets much easier. Just give it a try! ;-) – sɐunıɔןɐqɐp Sep 10 '18 at 13:49
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
- 470
- 6
- 21
-
+1 for bringing performance in. Indeed, iterating over the dictionary itself does include some overhead if all you need are values. That is mostly due to copying values or references into KeyValuePair structs. – Jaanus Varus Aug 05 '15 at 10:25
-
1FYI the last test in that link is test the wrong thing: it measures iterating over the keys, disregarding values, whereas the previous two tests do use the value. – Crescent Fresh Jul 13 '18 at 14:15
I found this method in the documentation for the DictionaryBase class on MSDN:
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.
-
3This looks like when using the non-generics version of Dictionary... i.e. prior to .NET framework 2.0. – joedotnot Apr 26 '14 at 13:21
-
@joed0tnot : it is the non-generics version used for `Hashtable` objects – sɐunıɔןɐqɐp Aug 01 '18 at 19:42
I know this is a very old question, but I created some extension methods that might be useful:
public static void ForEach<T, U>(this Dictionary<T, U> d, Action<KeyValuePair<T, U>> a)
{
foreach (KeyValuePair<T, U> p in d) { a(p); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.KeyCollection k, Action<T> a)
{
foreach (T t in k) { a(t); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.ValueCollection v, Action<U> a)
{
foreach (U u in v) { a(u); }
}
This way I can write code like this:
myDictionary.ForEach(pair => Console.Write($"key: {pair.Key}, value: {pair.Value}"));
myDictionary.Keys.ForEach(key => Console.Write(key););
myDictionary.Values.ForEach(value => Console.Write(value););
- 2,282
- 19
- 21
If you want to use for loop, you can do this:
var keyList=new List<string>(dictionary.Keys);
for (int i = 0; i < keyList.Count; i++)
{
var key= keyList[i];
var value = dictionary[key];
}
- 2,642
- 4
- 25
- 36
-
What is the benefit of this, though? It's longer code than a `foreach` loop _and_ worse performance because `new List
(dictionary.Keys)` will iterate `dictionary.Count` times before you even have a chance to iterate it yourself. Putting aside that asking for "the best way" is subjective, I don't see how this would qualify as either the "best way" or "standard way" that the question seeks. To "If you want to use for loop..." I would counter with "**Don't** use a `for` loop." – Lance U. Matthews May 15 '20 at 17:58 -
2If you have large collection and operations are slow in foreach and if your collection can change when you iterate, it protect you from "collection has changed" error and this solution has better performance then using ElementAt. – Seçkin Durgay May 16 '20 at 12:01
-
I agree that avoiding "Collection was modified" exceptions is one reason to do this, although that special case wasn't stated in the question and one could always do `foreach (var pair in dictionary.ToArray()) { }`. Still, I think it'd be good to make clear in the answer the specific scenario(s) in which one would want to use this code and the implications of doing so. – Lance U. Matthews May 16 '20 at 19:26
-
yes you are right but there is an answer here with ElementAt and it has very high reputation and i entered this answer :) – Seçkin Durgay May 16 '20 at 20:12
I will take the advantage of .NET 4.0+ and provide an updated answer to the originally accepted one:
foreach(var entry in MyDic)
{
// do something with entry.Value or entry.Key
}
- 4,102
- 5
- 40
- 60
The standard way to iterate over a Dictionary, according to official documentation on MSDN is:
foreach (DictionaryEntry entry in myDictionary)
{
//Read entry.Key and entry.Value here
}
- 107
- 3
- 11
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));
- 385
- 4
- 7
-
1You defined a `ForEach` method in which you have `foreach (...) { }`... Seems like unnecessary. – Maarten Mar 26 '19 at 13:51
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.
public new IEnumerator<T> GetEnumerator()
{
return this.Values.GetEnumerator();
}
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<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);
}
- 1,415
- 17
- 9
var dictionary = new Dictionary<string, int>
{
{ "Key", 12 }
};
var aggregateObjectCollection = dictionary.Select(
entry => new AggregateObject(entry.Key, entry.Value));
- 430
- 2
- 7
- 34
-
2There needs to be more justification/description in this answer. What does `AggregateObject` add to `KeyValuePair`? Where is the "iteration," as requested in the question? – Marc L. Dec 29 '17 at 16:37
-
Select iterates over dictionary and allows us to work on each object. It is not as general as `foreach`, but I've used it a lot. Did my answer truly deserve downvote? – Egor Okhterov Jun 02 '18 at 18:37
-
1No, `Select` *uses* iteration to effect the result, but is not an iterator itself. The types of things that iteration (`foreach`) is used for--especially operations with side-effects--are outside the scope of Linq, including `Select`. The lambda will not run until `aggregateObjectCollection` is actually enumerated. If this answer is taken as a "first path" (i.e., used before a straight `foreach`) it encourages bad practices. Situationally, there may Linq operations that are helpful *before* iterating a dictionary, but that doesn't address the question as asked. – Marc L. Jun 04 '18 at 16:11
The best answer is of course: Think, if you could use a more appropriate data structure than a dictionary if you plan to iterate over it- as Vikas Gupta mentioned already in the (beginning of the) discussion under the question. But that discussion as this whole thread still lacks surprisingly good alternatives. One is:
SortedList<string, string> x = new SortedList<string, string>();
x.Add("key1", "value1");
x.Add("key2", "value2");
x["key3"] = "value3";
foreach( KeyValuePair<string, string> kvPair in x )
Console.WriteLine($"{kvPair.Key}, {kvPair.Value}");
Why it could be argued a code smell of iterating over a dictionary (e.g. by foreach(KeyValuePair<,>) ?
A basic principle of Clean Coding: "Express intent!" Robert C. Martin writes in "Clean Code": "Choosing names that reveal intent". Obviously naming alone is too weak. "Express (reveal) intent with every coding decision" expresses it better.
A related principle is "Principle of least surprise" (=Principle of Least Astonishment).
Why this is related to iterating over a dictionary? Choosing a dictionary expresses the intent of choosing a data structure which was made for primarily finding data by key. Nowadays there are so much alternatives in .NET, if you want to iterate through key/value pairs that you could choose something else.
Moreover: If you iterate over something, you have to reveal something about how the items are (to be) ordered and expected to be ordered! Although the known implementations of Dictionary sort the key collection in the order of the items added- AFAIK, Dictionary has no assured specification about ordering (has it?).
But what are the alternatives?
TLDR:
SortedList: If your collection is not getting too large, a simple solution would be to use SortedList<,> which gives you also full indexing of key/value pairs.
Microsoft has a long article about mentioning and explaining fitting collections:
Keyed collection
To mention the most important: KeyedCollection<,> and SortedDictionary<,> . SortedDictionary<,> is a bit faster than SortedList for only inserting if it gets large, but lacks indexing and is needed only if O(log n) for inserting is preferenced over other operations. If you really need O(1) for inserting and accept slower iterating in exchange, you have to stay with simple Dictionary<,>. Obviously there is no data structure which is the fastest for every possible operation..
Additionally there is ImmutableSortedDictionary<,>.
And if one data structure is not exactly what you need, then derivate from Dictionary<,> or even from the new ConcurrentDictionary<,> and add explicit iteration/sorting functions!
- 3,169
- 27
- 27
Just wanted to add my 2 cent, as the most answers relate to foreach-loop. Please, take a look at the following code:
Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();
//Add some entries to the dictionary
myProductPrices.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.
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.
When you just want to "read" Keys and Values, you might also use IEnumerable.Select().
var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );
-
5Copying the entire collection for no reason at all will *not* improve performance. It'll dramatically slow down the code, as well as doubling the memory footprint of code that ought to consume virtually no additional memory. – Servy Sep 16 '16 at 16:08
-
I avoid the side-effect 'List.ForEach' method: `foreach` forces side-effect visibility up, where it belongs. – user2864740 Mar 28 '17 at 22:30
-
Unfortunately, you linked to a question and not a specific answer. There are 14 answers on that question, some of them lengthy. Can you link to the exact answer(s) that support(s) your statement that `.ForEach()` can improve performance over `foreach`? Better yet, also quote or describe the relevant parts of the answer because even Stack Overflow links can get broken (i.e. deleted answer). – Lance U. Matthews Feb 09 '21 at 23:15
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
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
}
- 1,240
- 4
- 21
- 36
-
5Creating and copying a second dictionary is not a valid solution to code readability. In fact, I would argue it would make the code harder to understand because now you have to ask yourself: "Why did the last guy create a second dictionary?" If you want to be more verbose, just use option one. – Matthew Goulart Sep 06 '18 at 19:23
-
I just meant to show you that when decl dict before for each, usage in the foreach is clear from the declaration – BigChief Sep 08 '18 at 09:03