Multi Value Dictionary?

后端 未结 10 1856
萌比男神i
萌比男神i 2020-11-27 20:45

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 somethi

相关标签:
10条回答
  • 2020-11-27 21:24

    Microsoft just added an official prelease version of exactly what you're looking for (called a MultiDictionary) 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.

    0 讨论(0)
  • 2020-11-27 21:25

    Alternative to custom type can be a generic extension that adds key and value when not found:

    public static V getValue<K, V>(this IDictionary<K, V> d, K key) where V : new() {
        V v; if (!d.TryGetValue(key, out v)) { v = new V(); d.Add(key, v); } return v; } 
    

    Sample use:

    var d = new Dictionary<int, LinkedList<int>>();
    d.getValue(1).AddLast(2);
    
    0 讨论(0)
  • 2020-11-27 21:28

    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);
      }
    
    }
    
    0 讨论(0)
  • 2020-11-27 21:33

    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.

    0 讨论(0)
  • 2020-11-27 21:33

    Yet here's my attempt using ILookup<TKey, TElement> and an internal KeyedCollection. Make sure the key property is immutable.
    Cross posted here.

    public class Lookup<TKey, TElement> : Collection<TElement>, ILookup<TKey, TElement>
    {
      public Lookup(Func<TElement, TKey> keyForItem)
        : base((IList<TElement>)new Collection(keyForItem))
      {
      }
    
      new Collection Items => (Collection)base.Items;
    
      public IEnumerable<TElement> this[TKey key] => Items[key];
      public bool Contains(TKey key) => Items.Contains(key);
      IEnumerator<IGrouping<TKey, TElement>>
        IEnumerable<IGrouping<TKey, TElement>>.GetEnumerator() => Items.GetEnumerator();
    
      class Collection : KeyedCollection<TKey, Grouping>
      {
        Func<TElement, TKey> KeyForItem { get; }      
        public Collection(Func<TElement, TKey> keyForItem) => KeyForItem = keyForItem;
        protected override TKey GetKeyForItem(Grouping item) => item.Key;
    
        public void Add(TElement item)
        {
          var key = KeyForItem(item);
          if (Dictionary != null && Dictionary.TryGetValue(key, out var collection))
            collection.Add(item);
          else
            Add(new Grouping(key) { item });
        }
    
        public bool Remove(TElement item)
        {
          var key = KeyForItem(item);
          if (Dictionary != null && Dictionary.TryGetValue(key, out var collection)
            && collection.Remove(item))
          {
            if (collection.Count == 0)
              Remove(key);
            return true;
          }
          return false;
        }
    
      }
      class Grouping : Collection<TElement>, IGrouping<TKey, TElement>
      {
        public Grouping(TKey key) => Key = key;
        public TKey Key { get; }
      }
    }
    
    0 讨论(0)
  • 2020-11-27 21:38

    You could use MultiDictionary class from PowerCollections.

    It returns ICollection{TValue} for the key asked.

    0 讨论(0)
提交回复
热议问题