多值字典?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多值字典?相关的知识,希望对你有一定的参考价值。

任何人都知道MultiValueDictionary的良好实施?基本上,我想要一些允许每个键有多个值的东西。我希望能够做类似的事情

dict.Add(key, val);

如果密钥尚不存在,它将添加它,如果它存在,它将只添加该密钥的另一个值。我只是要迭代它,所以我真的不关心其他检索方法。

答案

它不存在,但您可以从Dictionary和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
}
另一答案

自定义类型的替代方法可以是通用扩展,在未找到时添加键和值:

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; } 

样品用途:

var d = new Dictionary<int, LinkedList<int>>();
d.getValue(1).AddLast(2);
另一答案

微软刚刚在NuGet上添加了一个正式的预发布版本(称为MultiDictionary):https://www.nuget.org/packages/Microsoft.Experimental.Collections/

有关使用情况和更多详细信息,请访问官方MSDN博客文章:http://blogs.msdn.com/b/dotnet/archive/2014/06/20/would-you-like-a-multidictionary.aspx

我是此软件包的开发人员,如果您对性能或任何问题有任何疑问,请在此处或MSDN上告诉我。

希望有所帮助。

另一答案

您可以从列表字典轻松制作一个:

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);
  }

}
另一答案

您可以随时使用Tuple作为第二个通用参数:

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

或者甚至将通用List作为第二个通用参数:

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

这将允许您将多个值绑定到单个键。

为了便于使用,您可以创建一个扩展方法,以检查是否存在密钥并添加到列表中。

另一答案

这是我写的一篇你可以使用的。

它有一个继承自Dictionary的“MultiValueDictionary”类。

它还有一个扩展类,允许您在值类型为IList的任何Dictionary上使用特殊的Add功能;这样你就不会被迫使用自定义类,如果你不想这样做的话。

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);
    }
}
另一答案

你可以使用PowerCollections的MultiDictionary类。

它会返回ICollection {TValue}以获取所要求的密钥。

另一答案

只需将0.02美元添加到解决方案集合中:

我在2011年有同样的需求,并创建了一个MultiDictionary与所有.NET接口的迂回完整的实现。这包括返回标准KeyValuePair<K, T>的枚举数,并支持IDictionary<K, T>.Values属性,提供实际值的集合(而不是ICollection<ICollection<T>>)。

这样,它与.NET集合类的其余部分完全吻合。我还定义了一个IMultiDictionary<K, T>接口来访问特定于这种字典的操作:

public interface IMultiDictionary<TKey, TValue> :
  IDictionary<TKey, ICollection<TValue>>,
  IDictionary,
  ICollection<KeyValuePair<TKey, TValue>>,
  IEnumerable<KeyValuePair<TKey, TValue>>,
  IEnumerable {

  /// <summary>Adds a value into the dictionary</summary>
  /// <param name="key">Key the value will be stored under</param>
  /// <param name="value">Value that will be stored under the key</param>
  void Add(TKey key, TValue value);

  /// <summary>Determines the number of values stored under a key</summary>
  /// <param name="key">Key whose values will be counted</param>
  /// <returns>The number of values stored under the specified key</returns>
  int CountValues(TKey key);

  /// <summary>
  ///   Removes the item with the specified key and value from the dictionary
  /// </summary>
  /// <param name="key">Key of the item that will be removed</param>
  /// <param name="value">Value of the item that will be removed</param>
  /// <returns>True if the item was found and removed</returns>
  bool Remove(TKey key, TValue value);

  /// <summary>Removes all items of a key from the dictionary</summary>
  /// <param name="key">Key of the items that will be removed</param>
  /// <returns>The number of items that have been removed</returns>
  int RemoveKey(TKey key);

}

它可以在.NET 2.0以上的任何东西上编译,到目前为止我已经将它部署在Xbox 360,Windows Phone 7,Linux和Unity 3D上。还有一个完整的单元测试套件,涵盖了代码的每一行。

代码是根据Common Public License许可的(简短:任何事情都有,但是必须发布对库代码的错误修复)并且可以在my Subversion repository中找到。

另一答案

然而here是我尝试使用ILookup<TKey, TElement>和内部KeyedCollection。确保key属性是不可变的。 Cross发布了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>>.GetEnumerato

以上是关于多值字典?的主要内容,如果未能解决你的问题,请参考以下文章

多值字典?

Python 字典的一键多值,即一个键对应多个值

Python 2.7:将零添加到多值字典列表之间的大小差异并将其相加

数据结构相关模块(字典)

多值参数

Django 是不是支持多值 cookie?