9

I want to use a generic collection like Dictionary, but Dictionary requires that every key be unique. I have multiple values for the same "key", so I need a generic collection that will allow for that.

I realize that this makes the key no longer really a key, but I don't know what else to call it.

Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
richard
  • 12,263
  • 23
  • 95
  • 151
  • 1
    For anyone who cares, I ended up just including a reference to the value I wanted to track inside the value object. Then I just used a List and was able to access the value through the propery in my object. Thanks to everyone who answered. I will use this information for use in the future. – richard Mar 02 '11 at 22:52
  • possible duplicate of [Duplicate keys in .NET dictionaries?](http://stackoverflow.com/questions/146204/duplicate-keys-in-net-dictionaries) – nawfal Nov 05 '13 at 07:32

6 Answers6

21

Several options for you to consider:

  • use a Dictionary<TKey, List<TValue>> — keep a list of values for each key, not preventing duplicate values for the same key (i.e. duplicate pairs);
  • use a Dictionary<TKey, HashSet<TValue>> — keep a set of value for each key, preventing duplicate values for the same key;
  • use a List<KeyValuePair<TKey, TValue>> — keep a list of pair, not preventing duplicate values for the same key.

Note that in the latter case KeyValuePair is a struct, not a class, hence that implies a bit different handling.

The right option depends on your actual use case.

Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
  • I think your second suggestion makes the most sense to me. It would allow me to iterate over the keys and get the values, but wouldn't require the keys to be unique across the collection. Is that correct? – richard Mar 02 '11 at 22:35
  • Yes, that's correct. Also note that it won't prevent from storing duplicate pairs. If that's a concern, the first approach with a `HashSet` would be better. (Edited my answer to cover that.) – Ondrej Tucny Mar 02 '11 at 22:38
8

In .NET 3.5 and above, that is ILookup<TKey,TValue>. Unfortunately the only provided implementation is the immutable Lookup<TKey,TValue>, however it is easy to re-implement. An EditableLookup<TKey,TValue> is included in MiscUtil.

With an ILookup<TKey,TValue>, the TKey indexer returns an IEnumerable<TValue> (even if there were no matches for that key), so typical usage is:

foreach(var value in lookup[key])
    DoSomethingWith(value);
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
4

In C++, such a collection is called a multimap. A quick search for that term revealed this related question:

multimap in .NET

Community
  • 1
  • 1
razlebe
  • 7,134
  • 6
  • 42
  • 57
2

You can create a Dictionary<TKey,List<TValue>> and do the manual work yourself, but there is no "multi-dictionary" collection by default.

That said, if you have an IEnumerable you can convert it to a lookup which is like what you described, but can't be constructed by itself (have to call ToLookup() to create from enumeration).

James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
0

Try Dictionary<KeyType,List<ValueType>>.

You can create a custom dictionary which wraps this dictionary to handle all the required logic upon adding and removing.

Steven Jeuris
  • 18,274
  • 9
  • 70
  • 161
  • Dictionary will require _KeyType_ to be unique. I want to use the same value for the key more than once. – richard Mar 02 '11 at 22:32
0

For your value, you could store a list of whatever it is you want to hold.

overstood
  • 985
  • 6
  • 7