Подтвердить что ты не робот

Получение индекса словаря на основе item.key

Как я могу найти индекс элемента словаря на основе ключа элемента? Я использую следующий код для прохождения через словарь:

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

Может ли кто-нибудь помочь?

4b9b3361

Ответ 1

В индексе Dictionary нет понятия индекса. Вы не можете полагаться на любой порядок элементов внутри Dictionary. Альтернативой может быть 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;
}

Ответ 2

Невозможно получить индекс, поскольку данные хранятся в памяти совершенно по-разному для массива и словаря.

Когда вы объявляете массив любого типа, вы знаете, что данные будут помещаться в ячейки памяти один за другим. Таким образом, индекс представляет собой сдвиг адреса памяти.

Когда вы помещаете данные в словарь, вы не можете предсказать адрес, который будет использоваться для этого элемента, потому что он будет помещен в определенную пустую позицию, что обеспечит сбалансированный график для быстрого поиска по ключу. Таким образом, вы не можете манипулировать данными словаря с помощью индекса.

P.S. Я считаю, что вы можете решить свою проблему с помощью Linq.

Ответ 3

Возможно, что-то подобное может работать:

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

Основываясь на решении Dennis Traub, но используя словарь... (это заказчик по оригинальному добавлению)

Ответ 4

Это может сработать, и это, вероятно, не самый эффективный способ сделать это. Также я не уверен, почему вы хотели бы что-то вроде этого.

Int termIndex = Array.IndexOf(myDictionary.Keys.ToArray(), someKey);

Ответ 5

Существует 2 метода расширения

Указатель по ключу

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

Индекс по значению

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

Ответ 6

Как говорит Деннис, в словаре нет индекса, но в вашем примере позиция в цикле foreach может быть отслежена так:

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

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


            }

Ответ 7

Это старый, но кто-то может его использовать - в настоящее время я использую

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