Как я могу сохранить тот же ключ в IDictionary?

Я использую С# 4.0. Я хочу сохранить пару (строка, строка) с помощью IDictionary. как показано ниже:

Dictionary<string, string> _tempDicData = new Dictionary<string, string>();
      _tempDicData.Add("Hello", "xyz");
      _tempDicData.Add("Hello", "aaa");
      _tempDicData.Add("Hello", "qwert");
      _tempDicData.Add("Hello", "foo");
      _tempDicData.Add("Hello", "pqr");
      _tempDicData.Add("Hello", "abc");

но получил ошибку:

An item with the same key has already been added.

Итак, как я могу сохранить тот же ключ в IDictionary?


person Dharmik Bhandari    schedule 17.07.2012    source источник
comment
Какова ваша более широкая цель? Чего вы ожидаете достичь?   -  person penguat    schedule 17.07.2012
comment
Суть этого вопроса очень похожа на этот другой вопрос и его ответы могут помочь вам решить вашу проблему.   -  person O. R. Mapper    schedule 17.07.2012
comment
если вы хотите добавить несколько значений к одному и тому же ключу, почему бы вам не использовать string[] для значения вместо строки   -  person Maha Khairy    schedule 17.07.2012


Ответы (11)


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

class TDictionary<K, V>
{
    struct KeyValuePair
    {
        public K Key;
        public V Value;
    }

    private readonly List<KeyValuePair> fList = new List<KeyValuePair>();

    public void Add(K key, V value)
    {
        fList.Add(new KeyValuePair { Key = key, Value = value });
    }

    public List<V> this[K key]
    {
        get { return (from pair in fList where pair.Key.Equals(key) select pair.Value).ToList(); }
    }

    public List<K> Keys
    {
        get { return fList.Select(pair => pair.Key).ToList(); }
    }

    public List<V> Values
    {
        get { return fList.Select(pair => pair.Value).ToList(); }
    }
}
person Tomtom    schedule 17.07.2012

Вы не можете добавить один и тот же элемент в IDictionary<K,T> более одного раза — в этом весь смысл словаря, ассоциативного контейнера. Но вы можете заменить существующий следующим образом:

_tempDicData.Add("Hello", "xyz");
_tempDicData["Hello"] = "aaa";

и вы можете создать словарь списков, если вам нужно несколько элементов для каждого ключа:

IDictionary<string,IList<string>> _tempDicData =
    new Dictionary<string,IList<string>>();
IList<string> lst = new List<string>();
lst.Add("xyz");
lst.Add("aaa");
_tempDicData.Add("Hello", lst);

Если вы точно не знаете, существует ли список для ключа или нет, вы можете использовать этот шаблон для добавления новых элементов:

IList<string> lst;
if (!_tempDicData.TryGetValue("Hello", out lst)) {
    _tempDicData.Add("Hello", lst);
}
lst.Add("xyz");
lst.Add("aaa");
person Sergey Kalinichenko    schedule 17.07.2012

В словаре не может быть двух элементов с одним и тем же ключом. Однако у вас может быть один элемент, который сам является коллекцией:

Dictionary<string, List<string>> _tempDicData = new Dictionary<string, List<string>>
{
    { "Hello", new List<string> { "xyz", "aa", "foo" },
};

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

// WRONG: _tempDicData["Hello"] might not exist!
_tempDicData["Hello"].Add("bar");

// CORRECT:
if (!_tempDicData.ContainsKey("Hello")) {
    _tempDicData["Hello"] = new List<string>();
}
_tempDicData["Hello"].Add("bar");
person Jon    schedule 17.07.2012

Вы не можете. Словарь может содержать только один элемент для каждого ключа. Словарь, вероятно, не та структура данных, которую вы ищете.

person Marcus Johansson    schedule 17.07.2012

Создайте Dictionary<string,List<string>>.

Dictionary<string,List<string>> dict=new Dictionary<string,List<string>>();
dict.Add("hello",new List<string>());
dict["hello"].Add("foo");
dict["hello"].Add("bar");
person kv-prajapati    schedule 17.07.2012

Вы не можете сделать это с IDictionary. Попробуйте использовать NameValueCollection.

person Riccardo    schedule 17.07.2012

невозможно, создайте для этого свой класс с полями key value

person burning_LEGION    schedule 17.07.2012
comment
какой тип класса? Не могли бы вы дать мне подсказку для этого? - person Dharmik Bhandari; 17.07.2012
comment
открытый класс MyType {открытая строка Key {get; set;} public string Value {get; set;}} - person burning_LEGION; 17.07.2012

Вы не можете?

Вы можете использовать Dictionary<string, List<string>> или, если вам нужно решение только для чтения, вы можете использовать метод расширения ToLookup.

var lp = new[]
{
    Tuple.Create("Hello", "xyz"),
    Tuple.Create("Hello", "aaa"),
    Tuple.Create("Hello", "qwert"),
    Tuple.Create("Hello", "foo"),
    Tuple.Create("Hello", "pqr"),
    Tuple.Create("Hello", "abc"),
}.ToLookup(p => p.Item1, p => p.Item2);

foreach (var key in lp)
{
    foreach (var value in key)
    {
        Console.WriteLine("{0}: {1}", key.Key, value);
    }
}
person xanatos    schedule 17.07.2012

Ключ должен быть уникальным для поиска значений.

person Shailesh    schedule 17.07.2012

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

вы можете создать словарь >, но вам лучше перепланировать свои потребности.

person user1425690    schedule 17.07.2012

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

person Tomtom    schedule 17.07.2012