Есть ли в библиотеке базовых классов .NET какие-либо словарные классы, позволяющие использовать дублирующиеся ключи? Единственное решение, которое я нашел, - это создать, например, такой класс:
Dictionary<string, List<object>>
Но это довольно раздражает на самом деле использовать. Я полагаю, что в Java MultiMap выполняет это, но не может найти аналог в .NET.
c#
.net
dictionary
multimap
Механическая улитка
источник
источник
{ a, 1 }
и{ a, 2 }
в хеш-таблице, гдеa
они являются ключом, есть альтернатива{ a, [1, 2] }
.Ответы:
Если вы используете .NET 3.5, используйте
Lookup
класс.РЕДАКТИРОВАТЬ: вы обычно создаете
Lookup
использованиеEnumerable.ToLookup
. Это предполагает, что вам не нужно менять его потом - но я нахожу, что это достаточно хорошо.Если это не сработает для вас, я не думаю, что в рамках есть что-то, что поможет - и использование словаря так же хорошо, как и получается :(
источник
Lookup
не сериализуемоКласс List на самом деле работает довольно хорошо для коллекций ключ / значение, содержащих дубликаты, где вы хотели бы перебрать коллекцию. Пример:
источник
Вот один из способов сделать это с помощью List <KeyValuePair <string, string>>
Выходы k1 = v1, k1 = v2, k1 = v3
источник
Если вы используете строки как ключи и значения, вы можете использовать System.Collections.Specialized.NameValueCollection , которая будет возвращать массив строковых значений с помощью метода GetValues (строковый ключ).
источник
Я только что натолкнулся на библиотеку PowerCollections, которая включает, помимо прочего, класс MultiDictionary. Это аккуратно оборачивает этот тип функциональности.
источник
Очень важное замечание относительно использования Lookup:
Вы можете создать экземпляр объекта
Lookup(TKey, TElement)
, вызвавToLookup
объект, который реализуетIEnumerable(T)
Нет открытого конструктора для создания нового экземпляра
Lookup(TKey, TElement)
. Кроме того,Lookup(TKey, TElement)
объекты являются неизменяемыми, то есть вы не можете добавлять или удалять элементы или ключи изLookup(TKey, TElement)
объекта после его создания.(из MSDN)
Я думаю, что это будет шоу-стоппер для большинства применений.
источник
Я думаю, что-то вроде
List<KeyValuePair<object, object>>
бы сделал работу.источник
Если вы используете> = .NET 4, тогда вы можете использовать
Tuple
Class:источник
List<KeyValuePair<key, value>>
решение, как указано выше. Я ошибся?Достаточно легко «свернуть свою» версию словаря, которая допускает записи «дублирующихся ключей». Вот грубая простая реализация. Вы можете рассмотреть возможность добавления поддержки в основном для большинства (если не для всех)
IDictionary<T>
.Быстрый пример того, как его использовать:
источник
В ответ на оригинальный вопрос. Нечто подобное
Dictionary<string, List<object>>
реализовано в классе, названномMultiMap
вCode Project
.Вы можете найти больше информации по ссылке ниже: http://www.codeproject.com/KB/cs/MultiKeyDictionary.aspx
источник
NameValueCollection поддерживает несколько строковых значений под одним ключом (который также является строкой), но это единственный известный мне пример.
Я склонен создавать конструкции, подобные той, что в вашем примере, когда я сталкиваюсь с ситуациями, когда мне нужна такая функциональность.
источник
При использовании
List<KeyValuePair<string, object>>
опции вы можете использовать LINQ для поиска:источник
Так как новый C # (я полагаю, это из 7.0), вы также можете сделать что-то вроде этого:
и вы используете его как стандартный список, но с двумя значениями, которые вы хотите
источник
Вы имеете в виду конгруэнтный, а не фактический дубликат? В противном случае хеш-таблица не сможет работать.
Конгруэнтный означает, что два отдельных ключа могут хэшировать до эквивалентного значения, но ключи не равны.
Например: скажем, хеш-функция вашей хеш-таблицы была просто hashval = key mod 3. И 1, и 4 соответствуют 1, но имеют разные значения. Вот где ваша идея списка вступает в игру.
Когда вам нужно выполнить поиск 1, это значение хэшируется до 1, список просматривается до тех пор, пока ключ = 1 не будет найден.
Если вы разрешите вставку дубликатов ключей, вы не сможете различить, какие ключи соответствуют каким значениям.
источник
То, как я использую это просто
Dictionary<string, List<string>>
Таким образом, у вас есть один ключ, содержащий список строк.
Пример:
источник
Я наткнулся на этот пост в поисках того же ответа и не нашел ни одного, поэтому я подготовил примерное решение с использованием списка словарей, переопределив оператор [] для добавления нового словаря в список, когда все остальные имеют заданный ключ (установить) и вернуть список значений (получить).
Это некрасиво и неэффективно, ТОЛЬКО получает / устанавливает ключ, и всегда возвращает список, но работает:
источник
Я изменил ответ @Hector Correa на расширение с универсальными типами, а также добавил собственный TryGetValue.
источник
Это параллельный словарь для буксировки, я думаю, это поможет вам:
Примеры:
источник
я использую этот простой класс:
использование:
источник
Вы можете создать свою собственную обертку словаря, что-то вроде этого, в качестве бонуса она поддерживает нулевое значение в качестве ключа:
Образец использования:
источник
var dictionary = new OpenDictionary<string, int>(); dictionary.Add("1", 1); // The next line won't throw an exception; dictionary.Add("1", 2); dictionary.TryGetEntries("1", out List<int> result); // result is { 1, 2 }
Вы можете определить метод для построения составного строкового ключа каждый раз, когда вы хотите использовать словарь. Вы должны использовать этот метод для создания вашего ключа, например:
для использования:
источник
Дублирующиеся ключи нарушают весь контракт словаря. В словаре каждый ключ уникален и сопоставлен с одним значением. Если вы хотите связать объект с произвольным числом дополнительных объектов, лучшим вариантом может быть что-то похожее на DataSet (в общем на языке таблицы). Поместите свои ключи в один столбец, а свои значения - в другой. Это значительно медленнее, чем словарь, но это ваш компромисс за потерю способности хешировать ключевые объекты.
источник
Также это возможно:
Таким образом, мы можем иметь уникальные ключи. Надеюсь, что это работает для вас.
источник
Вы можете добавить одинаковые ключи в другом регистре, например:
key1
Key1
КЛЮЧ1
ключом1
ключом1
ключом1
Я знаю, это глупый ответ, но работал на меня.
источник