Вопрос по c#, list – c # словарь Как добавить несколько значений для одного ключа?

19

Я создал объект словаря

<code>Dictionary<string, List<string>> dictionary =
    new Dictionary<string,List<string>>();
</code>

Я хочу добавить строковые значения в список строк для данного отдельного ключа. Если ключ не существует, тогда я должен добавить новый ключ.List<string> не предопределено, я имею в виду, что я не создал ни одного объекта списка, а затем предоставилdictionary.Add("key",Listname), Как динамически создать этот список объектов вdictionary.Add("key",Listname) а затем добавить строки в этот список. Если мне нужно добавить 100 ключей, нужно ли создавать 100 списков перед выполнениемdictionary.Add инструкция, а также я должен pedefine содержимое этих списков?

Спасибо.

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

Ваш Ответ

11   ответов
2

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

void Add(string key, string val)
{
    List<string> list;

    if (!dictionary.TryGetValue(someKey, out list))
    {
       values = new List<string>();
       dictionary.Add(key, list);
    }

    list.Add(val);
}
2

Хорошая отправная точкаВот, Прямо по ссылке.

System.Collections.Specialized.NameValueCollection myCollection
    = new System.Collections.Specialized.NameValueCollection();

  myCollection.Add(“Arcane”, “http://arcanecode.com”);
  myCollection.Add(“PWOP”, “http://dotnetrocks.com”);
  myCollection.Add(“PWOP”, “http://dnrtv.com”);
  myCollection.Add(“PWOP”, “http://www.hanselminutes.com”);
  myCollection.Add(“TWIT”, “http://www.twit.tv”);
  myCollection.Add(“TWIT”, “http://www.twit.tv/SN”);
Error: User Rate Limit Exceeded sailer
Error: User Rate Limit Exceeded
0

var myData = new[]{new {a=1,b="frog"}, new {a=1,b="cat"}, new {a=2,b="giraffe"}};
ILookup<int,string> lookup = myData.ToLookup(x => x.a, x => x.b);
IEnumerable<string> allOnes = lookup[1]; //enumerable of 2 items, frog and cat

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

Error: User Rate Limit Exceeded sailer
0

Есть пакет NuGetЭкспериментальные коллекции Microsoft который содержит классMultiValueDictionary который делает именно то, что вам нужно.

Вот пост в блоге создателя пакета, который описывает его далее.

Вот еще одно сообщение в блоге, если вам интересно.

Example Usage:

MultiDictionary<string, int> myDictionary = new MultiDictionary<string, int>();
myDictionary.Add("key", 1);
myDictionary.Add("key", 2);
myDictionary.Add("key", 3);
//myDictionary["key"] now contains the values 1, 2, and 3
0

Я пытался добавить список к существующему ключу в словаре и нашел следующее решение:

Dictionary<string,List<string>> NewParent = new Dictionary<string,List<string>>();
child = new List<string> ();
child.Add('SomeData');
NewParent["item1"].AddRange(child);

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

28

Update: проверить существование, используяTryGetValue сделать только один поиск в случае, если у вас есть список:

List<int> list;

if (!dictionary.TryGetValue("foo", out list))
{
    list = new List<int>();
    dictionary.Add("foo", list);
}

list.Add(2);


Original: Проверьте наличие и добавьте один раз, затем введите словарь, чтобы получить список, и добавьте в список как обычно:

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

if (!dictionary.ContainsKey("foo"))
    dictionary.Add("foo", new List<int>());

dictionary["foo"].Add(42);
dictionary["foo"].AddRange(oneHundredInts);

Или жеList<string> как в твоем случае.

Кроме того, если вы знаете, сколько элементов вы собираетесь добавить в динамическую коллекцию, такую какList<T>В пользу конструктора, который занимает начальную емкость списка:new List<int>(100);.

Это займет память, необходимую для удовлетворения указанной емкостиupfrontвместо того, чтобы хвататься за маленькие кусочки каждый раз, когда он начинает заполняться. Вы можете сделать то же самое со словарями, если знаете, что у вас есть 100 ключей.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

) Мой - другой, и он использует механизм расширения как удобный способ выполнения (удобно):

public static void AddToList<T, U>(this IDictionary<T, List<U>> dict, T key, U elementToList)
{

    List<U> list;

    bool exists = dict.TryGetValue(key, out list);

    if (exists)
    {
        dict[key].Add(elementToList);
    }
    else
    {
        dict[key] = new List<U>();
        dict[key].Add(elementToList);
    }

}

Затем вы используете его следующим образом:

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

dict.AddToList(4, "test1");
dict.AddToList(4, "test2");
dict.AddToList(4, "test3");

dict.AddToList(5, "test4");
3

которая вытекает изDictionary<K, List<V>>, Это не идеально, однако это делает хорошую работу.

/// <summary>
/// Represents a collection of keys and values.
/// Multiple values can have the same key.
/// </summary>
/// <typeparam name="TKey">Type of the keys.</typeparam>
/// <typeparam name="TValue">Type of the values.</typeparam>
public class MultiMap<TKey, TValue> : Dictionary<TKey, List<TValue>>
{

    public MultiMap()
        : base()
    {
    }

    public MultiMap(int capacity)
        : base(capacity)
    {
    }

    /// <summary>
    /// Adds an element with the specified key and value into the MultiMap. 
    /// </summary>
    /// <param name="key">The key of the element to add.</param>
    /// <param name="value">The value of the element to add.</param>
    public void Add(TKey key, TValue value)
    {
        List<TValue> valueList;

        if (TryGetValue(key, out valueList)) {
            valueList.Add(value);
        } else {
            valueList = new List<TValue>();
            valueList.Add(value);
            Add(key, valueList);
        }
    }

    /// <summary>
    /// Removes first occurence of an element with a specified key and value.
    /// </summary>
    /// <param name="key">The key of the element to remove.</param>
    /// <param name="value">The value of the element to remove.</param>
    /// <returns>true if the an element is removed;
    /// false if the key or the value were not found.</returns>
    public bool Remove(TKey key, TValue value)
    {
        List<TValue> valueList;

        if (TryGetValue(key, out valueList)) {
            if (valueList.Remove(value)) {
                if (valueList.Count == 0) {
                    Remove(key);
                }
                return true;
            }
        }
        return false;
    }

    /// <summary>
    /// Removes all occurences of elements with a specified key and value.
    /// </summary>
    /// <param name="key">The key of the elements to remove.</param>
    /// <param name="value">The value of the elements to remove.</param>
    /// <returns>Number of elements removed.</returns>
    public int RemoveAll(TKey key, TValue value)
    {
        List<TValue> valueList;
        int n = 0;

        if (TryGetValue(key, out valueList)) {
            while (valueList.Remove(value)) {
                n++;
            }
            if (valueList.Count == 0) {
                Remove(key);
            }
        }
        return n;
    }

    /// <summary>
    /// Gets the total number of values contained in the MultiMap.
    /// </summary>
    public int CountAll
    {
        get
        {
            int n = 0;

            foreach (List<TValue> valueList in Values) {
                n += valueList.Count;
            }
            return n;
        }
    }

    /// <summary>
    /// Determines whether the MultiMap contains an element with a specific
    /// key / value pair.
    /// </summary>
    /// <param name="key">Key of the element to search for.</param>
    /// <param name="value">Value of the element to search for.</param>
    /// <returns>true if the element was found; otherwise false.</returns>
    public bool Contains(TKey key, TValue value)
    {
        List<TValue> valueList;

        if (TryGetValue(key, out valueList)) {
            return valueList.Contains(value);
        }
        return false;
    }

    /// <summary>
    /// Determines whether the MultiMap contains an element with a specific value.
    /// </summary>
    /// <param name="value">Value of the element to search for.</param>
    /// <returns>true if the element was found; otherwise false.</returns>
    public bool Contains(TValue value)
    {
        foreach (List<TValue> valueList in Values) {
            if (valueList.Contains(value)) {
                return true;
            }
        }
        return false;
    }

}

Обратите внимание, чтоAdd Метод ищет, если ключ уже присутствует. Если ключ новый, создается новый список, значение добавляется в список, а список добавляется в словарь. Если ключ уже присутствовал, новое значение добавляется в существующий список.

Error: User Rate Limit ExceededIDictionary<K,V>Error: User Rate Limit ExceededDictionary<K,List<V>>Error: User Rate Limit ExceededIDictionary<K,V>Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededDictionary<TKey, HashSet<TValue>>Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededMultiMapError: User Rate Limit ExceededMultiMapError: User Rate Limit ExceededMultiSetError: User Rate Limit Exceeded
8

Если я понял, что вы хотите:

dictionary.Add("key", new List<string>()); 

потом...

dictionary["key"].Add("string to your list");
6
Dictionary<string, List<string>> dictionary = new Dictionary<string,List<string>>();

foreach(string key in keys) {
    if(!dictionary.ContainsKey(key)) {
        //add
        dictionary.Add(key, new List<string>());
    }
    dictionary[key].Add("theString");
}

Если ключ не существует, новыйList добавлено (внутри, если). В противном случае ключ существует, поэтому просто добавьте новое значение кList под этим ключом.

0

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

List<string> list;
if (dictionary.ContainsKey(key)) {
  list = dictionary[key];
} else {
  list = new List<string>();
  dictionary.Add(ley, list);
}
list.Add(value);

Похожие вопросы