Как получить относительную позицию элемента словаря? - PullRequest
2 голосов
/ 22 сентября 2010

У меня есть следующий код C #:

    Dictionary<string, int> d = new Dictionary<string, int>();
    d.Add("a", 3);
    d.Add("b", 1);
    d.Add("c", 0);
    d.Add("d", -1);
    d.Add("e", -9);

При поиске клавиши "c" я хочу получить позицию этой клавиши, т.е. 2. Если я ищу клавишу "e", яхочу получить 4. Если элемент не найден, относительная позиция может быть -1.

Добавлено: Если у вас нет лучшей идеи, я хочу заполнить матрицу определенными значениями в номере строки, указанномотносительная позиция найденного элемента словаря.То же самое относится и к столбцу, но с использованием другого словаря.Пример:

     n4   n2   n1   n3  n9  . . . 
a   4/4
b              2         8
c
d                  8/2
e         4/3
.
.
.

Где a, b, c, d, e, ... - ключи словарей "d", а n4, n2, n3, n9 - ключи второго словаря.

Как я могу получить это?

Ответы [ 5 ]

9 голосов
/ 22 сентября 2010

Внутри Dictionary<,> нет такого понятия, как «позиция» - это неупорядоченная коллекция.

Существуют похожие коллекции, отсортированные по ключу - SortedList<,> и SortedDictionary<,>.Обратите внимание, что они упорядочены по ключу, а не по времени вставки.Непонятно, что вы хотите.

1 голос
/ 10 июля 2013

Это должно сработать:

d.Keys.ToList().IndexOf("c");

Обратите внимание, что поиск по времени O (1), предлагаемый Словарём, теряется при преобразовании в Список, потому что Списки по своей сути O (n).Поэтому, если в вашем Словаре большое количество элементов, вам, вероятно, лучше использовать другое измерение словаря или матрицы для хранения позиций, поскольку их получение таким образом, вероятно, будет медленнее.На самом деле, вы, вероятно, должны предположить, что приведенная выше строка одинакова:

GetDictKeyPos(d, "c");

public int GetDictKeyPos(Dictionary<string, int> d, string key)
{
    for (int i = 0; i < d.Count; ++i)
    {
        if (d.ElementAt(i).Key == key)
            return i;
    }
    return -1;
}

В качестве примечания , если вы пытаетесь получить позицию, вы, вероятно,сделав предположение, что положение сохранено.Microsoft говорит, что не рассчитывайте на это, но на практике вы обнаружите, что, вероятно, можете рассчитывать на это.(Я никогда не видел, чтобы положение не было сохранено.) При этом, пока Microsoft не признает, что: «Да, да, мы держимся за вас: положение фактически сохраняется в словаре. Мы просто не хотелиПризнайте это, потому что мы хотели иметь возможность изменить его, если мы нашли лучшую реализацию, но теперь мы знаем, что собираемся оставить это, так что вы идете ... ", вы, вероятно, не должны предполагать, что позиция сохранена.

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

1 голос
/ 22 сентября 2010

Словари не имеют подразумеваемого порядка пар ключ-значение.Если вам нужна «позиция», вы используете их неправильно.

При редактировании: Если вы реализуете матрицу, лучшим вариантом будет использование многомерного массива.Например:

int[,] matrix = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };

Эквивалентно такой матрице, как:

1 2
3 4
5 6

Вы можете получить доступ к ее элементам, используя matrix[i][j];например, matrix[0][0] равно 1, matrix[0][1] равно 2 и т. д.

0 голосов
/ 24 сентября 2010

Вы не сможете использовать ни одну из встроенных структур данных коллекции, включая KeyedCollection.Тем не менее, вы можете легко создать свой собственный класс коллекции, производный от Collection и содержащий внутри Dictionary для быстрого поиска ключа.Сам класс Collection предоставляет возможность индексированного поиска.

public class KeyValueCollection<TKey, TValue> : Collection<KeyValuePair<TKey, TValue>>
{
    private Dictionary<TKey, TValue> m_Dictionary = new Dictionary<TKey, TValue>();

    public TValue GetValue(TKey key)
    {
        return m_Dictionary[key];
    }

    public void Add(TKey key, TValue value)
    {
        m_Dictionary.Add(key, value);
        base.Add(new KeyValuePair<TKey, TValue>(key, value));
    }

    protected override void ClearItems()
    {
        m_Dictionary.Clear();
        base.ClearItems();
    }

    protected override void InsertItem(int index, KeyValuePair<TKey, TValue> item)
    {
        m_Dictionary.Add(item.Key, item.Value);
        base.InsertItem(index, item);
    }

    protected override void RemoveItem(int index)
    {

        m_Dictionary.Remove(this[index].Key);
        base.RemoveItem(index);
    }

    protected override void SetItem(int index, KeyValuePair<TKey, TValue> item)
    {
        m_Dictionary[this[index].Key] = item.Value;
        base.SetItem(index, item);
    }
}
0 голосов
/ 22 сентября 2010

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

(ИЛИ)

Возможно, вы хотитепросто поддерживать список структур, которые хранят

   [{"a",-1},{"b",1},{"c",0},{"d",-1},{"e",-9}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...