Iterate over C # dictionary keys with index?

How to iterate over dictionary keys while maintaining a key index. I merged a foreach -loop with the local variable i , which is incremented by one for each round of the loop.

Here is my code that works:

 public IterateOverMyDict() { int i=-1; foreach (string key in myDict.Keys) { i++; Console.Write(i.ToString() + " : " + key); } } 

However, using the local variable i seems very low-tech. I was wondering if there is a way that I do not need to use the "extra" variable? Not to say that this is bad, but is there any better?

+7
source share
4 answers

There is no such thing as a key index. You should always treat Dictionary<TKey, TValue> as an unpredictable order โ€” where the order you get when you repeat it may change. (So, theoretically, you can add one new record, and the records may be in a completely different order the next time you repeat them. Theoretically, this can happen without changing the data, but this is less likely in normal implementations.)

If you really want to get the numerical index that you observed this time, you can use:

 foreach (var x in dictionary.Select((Entry, Index) => new { Entry, Index })) { Console.WriteLine("{0}: {1} = {2}", x.Index, x.Entry.Key, x.Entry.Value); } 

... but keep in mind that this is a pretty misleading display as it offers a built-in order.

From the documentation :

For enumeration purposes, each element in the dictionary is considered as a structure KeyValuePair<TKey, TValue> , representing the value and its key. The order in which elements are returned is undefined.

EDIT: if you don't like the Select call here, you can create your own extension method:

 public struct IndexedValue<T> { private readonly T value; private readonly int index; public T Value { get { return value; } } public int Index { get { return index; } } public IndexedValue(T value, int index) { this.value = value; this.index = index; } } public static class Extensions { public static IEnumerable<IndexedValue<T>> WithIndex<T> (this IEnumerable<T> source) { return source.Select((value, index) => new IndexedValue<T>(value, index)); } } 

Then your loop will look like this:

 foreach (var x in dictionary.WithIndex()) { Console.WriteLine("{0}: {1} = {2}", x.Index, x.Value.Key, x.Value.Value); } 
+18
source

Technically, the key is the index in the Dictionary<TKey, TValue> . You cannot get items in a specific order, so there really is no numerical index to be applied.

+3
source

Not really. Note that the keys in the dictionary are not logically โ€œorderedโ€. They have no index. There is no first or last key, from the point of view of the Dictionary. You can independently track whether this is the first key returned by the enumerator, how you do it, but there is no concept in the dictionary โ€œgive me the 5th keyโ€, so you cannot use a for loop with an indexer, as you could with a list or array.

+1
source

Dictionaries are not exactly lists, arrays, or vectors. They make these designs one more step. The key may be an index:

 Dictionary myDictionary<int, string> = new Dictionary<int, string>() { {0, "cat"}, {1, "dog"}, {2, "pig"}, {3, "horse"} }; myDictionary[4] = "hat"; for int i = 0; i <5; i++){ Console.Writeline(myDictionary[i]); } 

At the moment, you probably do not get most of the benefits of the dictionary (which is similar to listing with the benefit of quick sorting by key values) and uses it as a list.

0
source

All Articles