2012-11-21 12 views
11

Jak znaleźć indeks elementu słownika na podstawie klucza elementu? Używam następującego kodu, aby przejść przez słownik:Pobieranie indeksu elementu słownika na podstawie elementu item.key

foreach (var entry in freq) 
{ 
    var word = entry.Key; 
    var wordFreq = entry.Value; 
    int termIndex = ??????; 
} 

Czy ktoś może pomóc?

+3

"Słownik" nie jest kolekcją, która ma indeks numeryczny. Zamiast tego możesz użyć ['OrderedDictionary'] (http://msdn.microsoft.com/en-us/library/system.collections.specialized.ordereddictionary.aspx). –

+0

Bardzo [ściśle powiązane pytanie] (https://stackoverflow.com/q/4538894/465053). – RBT

Odpowiedz

9

Brak koncepcji indeksu w Dictionary. Nie można polegać na żadnych zamówieniach produktów wewnątrz Dictionary. Alternatywą może być OrderedDictionary.

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

Działa to tylko wtedy, gdy wszystkie wartości są unikalne w słowniku, co niekoniecznie musi się zdarzyć. –

1

Jak Dennis twierdzi, nie ma indeksu w słowniku, ale w swoim przykładzie pozycja w pętli foreach mogą być śledzone, jak tak:

int index = -1; 
foreach (var entry in freq) 
      { 

       var word = entry.Key; 
       var wordFreq = entry.Value; 
       int termIndex = ++index; 


      } 
+0

Jest to niepoprawne z powodu przyrostu postu - zwróci -1, 0, 1 itd. Powinien to być indeks '++ '. –

+0

Cholera! masz rację. dzięki teraz poprawione. – Richard

+0

Chłopaki, mam pytanie filozoficzne, w jaki sposób zamierzasz używać tego indeksu? – Warlock

6

Nie ma sposobu, aby uzyskać indeks, od przechowywania danych w pamięci na zupełnie inne sposoby dla tablicy i słownika.

Po zadeklarowaniu tablicy dowolnego typu wiadomo, że dane będą umieszczane w komórkach pamięci jeden po drugim. Indeks jest więc przesunięciem adresu pamięci.

Po umieszczeniu danych w słowniku nie można przewidzieć adresu, który będzie używany dla tego elementu, ponieważ zostanie on umieszczony w określonej pustej pozycji, która zapewni zrównoważony wykres dla szybkiego wyszukiwania według klucza. Tak więc nie można manipulować danymi słownika za pomocą indeksu.

P.S. Uważam, że możesz rozwiązać swój problem za pomocą Linq.

3

Może coś takiego może działać:

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

oparciu o rozwiązania Dennis Traub, ale przy użyciu słownika ... (To zamawiający przez pierwotnego dodatkowo)

+0

Nie rozumiem twojego pytania ... – rasputino

2

Jest 2 metody przedłużania

Indeks według klucza

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

Główna wartością

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

To stary, ale ktoś może go używać - Używam obecnie

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

To może działać, a nie jest to prawdopodobnie najbardziej skuteczny sposób to zrobić. Również nie jestem pewien, dlaczego chcesz coś takiego.

Int termIndex = Array.IndexOf(myDictionary.Keys.ToArray(), someKey); 
Powiązane problemy