Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi Value Dictionary?

Anyone know of a good implementation of a MultiValueDictionary? Basically, I want something that allows multiple values per key. I want to be able to do something like

dict.Add(key, val);

And if the key doesn't already exist, it will add it, if it does, it will just add another value to that key. I'm just going to iterate over it, so I don't really care about the other retrieval methods.

like image 253
mpen Avatar asked Oct 03 '10 18:10

mpen


People also ask

Can dictionary key have multiple values?

General Idea: In Python, if we want a dictionary to have multiple values for a single key, we need to store these values in their own container within the dictionary. To do so, we need to use a container as a value and add our multiple values to that container. Common containers are lists, tuples, and sets.

What are dictionary values?

Python dictionary | values() values() is an inbuilt method in Python programming language that returns a view object. The view object contains the values of the dictionary, as a list. If you use the type() method on the return value, you get “dict_values object”. It must be cast to obtain the actual list.

How do you add multiple key-value pairs in a dictionary?

In Python, we can add multiple key-value pairs to an existing dictionary. This is achieved by using the update() method. This method takes an argument of type dict or any iterable that has the length of two - like ((key1, value1),) , and updates the dictionary with new key-value pairs.


5 Answers

Microsoft just added an official prelease version of exactly what you're looking for (called a MultiValueDictionary) available through NuGet here: https://www.nuget.org/packages/Microsoft.Experimental.Collections/

Info on usage and more details can be found through the official MSDN blog post here: http://blogs.msdn.com/b/dotnet/archive/2014/06/20/would-you-like-a-multidictionary.aspx

I'm the developer for this package, so let me know either here or on MSDN if you have any questions about performance or anything.

Hope that helps.

like image 124
Ian Hays Avatar answered Nov 02 '22 04:11

Ian Hays


You can easily make one from a dictionary of lists:

public class MultiValueDictionary<Key, Value> : Dictionary<Key, List<Value>> {

  public void Add(Key key, Value value) {
    List<Value> values;
    if (!this.TryGetValue(key, out values)) {
      values = new List<Value>();
      this.Add(key, values);
    }
    values.Add(value);
  }

}
like image 26
Guffa Avatar answered Nov 02 '22 02:11

Guffa


It doesn't exist, but you can build one pretty quickly from Dictionary and List:

class MultiDict<TKey, TValue>  // no (collection) base class
{
   private Dictionary<TKey, List<TValue>> _data =  new Dictionary<TKey,List<TValue>>();

   public void Add(TKey k, TValue v)
   {
      // can be a optimized a little with TryGetValue, this is for clarity
      if (_data.ContainsKey(k))
         _data[k].Add(v);
      else
        _data.Add(k, new List<TValue>() { v}) ;
   }

   // more members
}
like image 33
Henk Holterman Avatar answered Nov 02 '22 04:11

Henk Holterman


You can always use a Tuple for your second generic parameter:

var dict = new Dictionary<string,Tuple<string,int,object>>();
dict.Add("key", new Tuple<string,int,object>("string1", 4, new Object()));

Or even , a generic List as a second generic parameter:

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

That will allow you to bind multiple values to a single key.

For ease of use, you can create an extension method that will check for existence of a key and addition to the list.

like image 44
Oded Avatar answered Nov 02 '22 04:11

Oded


Here's one I wrote a while back that you can use.

It has a "MultiValueDictionary" class that inherits from Dictionary.

It also has an extension class that allows you to use the special Add functionality on any Dictionary where the value type is an IList; that way you're not forced to use the custom class if you don't want to.

public class MultiValueDictionary<KeyType, ValueType> : Dictionary<KeyType, List<ValueType>>
{
    /// <summary>
    /// Hide the regular Dictionary Add method
    /// </summary>
    new private void Add(KeyType key, List<ValueType> value)
    {            
        base.Add(key, value);
    }

    /// <summary>
    /// Adds the specified value to the multi value dictionary.
    /// </summary>
    /// <param name="key">The key of the element to add.</param>
    /// <param name="value">The value of the element to add. The value can be null for reference types.</param>
    public void Add(KeyType key, ValueType value)
    {
        //add the value to the dictionary under the key
        MultiValueDictionaryExtensions.Add(this, key, value);
    }
}

public static class MultiValueDictionaryExtensions
{
    /// <summary>
    /// Adds the specified value to the multi value dictionary.
    /// </summary>
    /// <param name="key">The key of the element to add.</param>
    /// <param name="value">The value of the element to add. The value can be null for reference types.</param>
    public static void Add<KeyType, ListType, ValueType>(this Dictionary<KeyType, ListType> thisDictionary, 
                                                         KeyType key, ValueType value)
    where ListType : IList<ValueType>, new()
    {
        //if the dictionary doesn't contain the key, make a new list under the key
        if (!thisDictionary.ContainsKey(key))
        {
            thisDictionary.Add(key, new ListType());
        }

        //add the value to the list at the key index
        thisDictionary[key].Add(value);
    }
}
like image 4
Doctor Jones Avatar answered Nov 02 '22 02:11

Doctor Jones