Reputation: 2057
How can I find the index of an element of a dictionary based on the element key? I'm using the following code to go through the dictionary:
foreach (var entry in freq)
{
var word = entry.Key;
var wordFreq = entry.Value;
int termIndex = ??????;
}
Could anyone help please?
Upvotes: 15
Views: 55872
Reputation: 601
The dictionary implementation in .NET hashtable has no defined index because it is based on a hash key. I find the answers here to be inefficient and slow because many of these solutions do not preserve the time complexity of the O (1) Dictionary data structure. The ordered dictionary has some performance disadvantages compared to the dictionary.
The only once efficient possible solution is to add an index while building the dictionary. So you should have e.g.
Dictionary<string, Tuple <int, int >>
where in the tuple you would add an index if you add a new key-value pair. This simple solution preserves the time O (1) and in addition you can have a property with an index.
Upvotes: 0
Reputation: 89
This might work and this is probably not the most efficient way of doing this. Also im not sure why you would want something like this.
Int termIndex = Array.IndexOf(myDictionary.Keys.ToArray(), someKey);
Upvotes: 7
Reputation: 111
It's old but someone might use it - I currently use
public static int OrderedDictIndexOfKey(string key, OrderedDictionary oDict)
{
int i = 0;
foreach (DictionaryEntry oDictEntry in oDict)
{
if ((string)oDictEntry.Key == key) return i;
i++;
}
return -1;
}
public static object OrderedDictKeyAtIndex(int index, OrderedDictionary oDict)
{
if (index < oDict.Count && index >= 0)
{
return oDict.Cast<DictionaryEntry>().ElementAt(index).Key;
}
else
{
return null;
}
}
Upvotes: 1
Reputation: 231
There is 2 extension methods
Index by key
public static int IndexOf<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
int i = 0;
foreach(var pair in dictionary)
{
if(pair.Key.Equals(key))
{
return i;
}
i++;
}
return -1;
}
Index by value
public static int IndexOf<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TValue value)
{
int i = 0;
foreach(var pair in dictionary)
{
if(pair.Value.Equals(value))
{
return i;
}
i++;
}
return -1;
}
Upvotes: 4
Reputation: 799
Maybe something like this could work:
public static int GetIndex(Dictionary<string, object> dictionary, string key)
{
for (int index = 0; index < dictionary.Count; index++)
{
if(dictionary.Skip(index).First().Key == key)
return index;
}
return -1;
}
Based on Dennis Traub solution, but using a Dictionary... (it's orderer by the original addition)
Upvotes: 3
Reputation: 51634
There is no concept of an index in a Dictionary
. You can't rely on any order of items inside the Dictionary
. The OrderedDictionary
might be an alternative.
var freq = new OrderedDictionary<string, int>();
// ...
foreach (var entry in freq)
{
var word = entry.Key;
var wordFreq = entry.Value;
int termIndex = GetIndex(freq, entry.Key);
}
public int GetIndex(OrderedDictionary<string, object> dictionary, string key)
{
for (int index = 0; index < dictionary.Count; index++)
{
if (dictionary.Item[index] == dictionary.Item[key])
return index; // We found the item
}
return -1;
}
Upvotes: 10
Reputation: 7471
There is no way to get index, since data storing in memory in absolutely different ways for array and dictionary.
When you declare array of any type, you know, that data will be placed in memory cells one after the other. So, index is a shift of memory address.
When you put data in a dictionary, you can't predict the address, that will be used for this item, because it will be placed in specific empty position, which will provide balanced graph for fast search by key. So, you can't manipulate with dictionary data using index.
P.S. I believe, that you can resolve your problem using Linq.
Upvotes: 6
Reputation: 22016
As Dennis states there is no index in dictionary but in your example the position in the foreach loop could be tracked as so:
int index = -1;
foreach (var entry in freq)
{
var word = entry.Key;
var wordFreq = entry.Value;
int termIndex = ++index;
}
Upvotes: 1