2010-09-03 4 views
25

Мне нужен словарь, похожий на объект, который может хранить несколько записей с одним и тем же ключом. Является ли это доступным как стандартная коллекция, или мне нужно катиться самостоятельно?Словарь с несколькими записями с тем же ключом

Чтобы уточнить, я хочу, чтобы иметь возможность сделать что-то вроде этого:

var dict = new Dictionary<int, String>(); 
dict.Add(1, "first"); 
dict.Add(1, "second"); 

foreach(string x in dict[1]) 
{ 
    Console.WriteLine(x); 
} 

Выход:

first 
second 
+0

Вы хотите конкретно использовать int для ключа? Если строка будет достаточной, может быть полезно имя NameValueCollection - несколько значений могут быть назначены ключу –

ответ

42

В .NET 3.5 вы можете использовать Lookup вместо словаря.

var items = new List<KeyValuePair<int, String>>(); 
items.Add(new KeyValuePair<int, String>(1, "first")); 
items.Add(new KeyValuePair<int, String>(1, "second")); 
var lookup = items.ToLookup(kvp => kvp.Key, kvp => kvp.Value); 

foreach (string x in lookup[1]) 
{ 
    Console.WriteLine(x); 
} 

Категория Lookup неизменна. Если вы хотите изменить версию, вы можете использовать EditableLookup от MiscUtil.

+1

Из документов: * Нет никакого открытого конструктора для создания нового экземпляра Lookup . Кроме того, объекты Lookup неизменяемы, то есть вы не можете добавлять или удалять элементы или ключи из объекта Lookup после его создания. * – Douglas

+0

@Douglas: Спасибо за комментарий. Я обновил свой ответ, чтобы охватить этот момент. –

9

Я рекомендовал бы делать что-то вроде этого:

var dict = new Dictionary<int, HashSet<string>>(); 
dict.Add(1, new HashSet<string>() { "first", "second" }); 
6

Dictionary<T,K> не поддерживает такое поведение, и в библиотеке базового класса нет такой коллекции, обеспечивающей такое поведение. Самый простой способ построить составную структуру данных, как это:

var data = new Dictionary<int, List<string>>(); 

В качестве второго параметра следует использовать коллекцию, которая обеспечивает качества, которые вы ищете, то есть стабильный порядок ⇒ List<T>, быстрый доступ HashSet<T> и т.д.

1

То, что вы ищете, на самом деле не является Словарем в традиционном смысле (см. Associative Array).

Там нет класса, насколько мне известно, что предлагает это в рамках (System.Linq.Lookup не предоставляет конструктор), но вы можете создать класс самостоятельно, который реализует ILookup<TKey, TElement>

0

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

2

Вы определенно хотите использовать NameValueCollection:

использованием System.Collections.Specialized;

NameValueCollection nvc = new NameValueCollection(); 
nvc.Add("pets", "Dog"); 
nvc.Add("pets", "Rabbit"); 
Console.WriteLine(nvc["pets"]); 
//returns Dog,Rabbit 
+5

NVC работает только со строками. – oillio

Смежные вопросы