How to change an ILookup object in C # 4.0?

Before .NET 3.5, I used

Dictionary<TKey, List<TValue>> 

for data storage. But I just discovered that .NET 3.5 provides a new collection type, which is an ILookup class that can represent my old complex data type.

I always create an ILookup object using the LINQ extension method (ToLookup method). But I do not know how to change the ILookup object.

Is it possible? Or I need to create using the union method and call the ToLookup method again.

Thanks,

+4
source share
3 answers

You will not do it, it is immutable. You have indicated both of the reasonable options; either use the dictionary of subcategories, or continue to create new search queries.

+4
source

Here is an example implementation of ILookup that can be manipulated. It wraps around the Dictionary element of the List elements. He is completely general. I could not come up with a better name. :)

 public class LookupDictionary<TKey, TElement> : ILookup<TKey, TElement> { private Dictionary<TKey, List<TElement>> _dicLookup = new Dictionary<TKey, List<TElement>>(); public LookupDictionary() { } public LookupDictionary(ILookup<TKey, TElement> a_lookup) { foreach (var grouping in a_lookup) { foreach (var element in grouping) AddElement(grouping.Key, element); } } public IEnumerable<TElement> AllElements { get { return (from key in _dicLookup.Keys select _dicLookup[key]) .SelectMany(list => list); } } public int Count { get { return AllElements.Count(); } } public IEnumerable<TElement> this[TKey a_key] { get { List<TElement> list; if (_dicLookup.TryGetValue(a_key, out list)) return list; return new TElement[0]; } } public bool Contains(TKey a_key) { return _dicLookup.ContainsKey(a_key); } public void Add(TKey a_key, TElement a_element) { AddElement(a_key, a_element); } public void RemoveKey(TKey a_key) { _dicLookup.Remove(a_key); } public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() { return GetGroupings().GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return (GetGroupings() as System.Collections.IEnumerable).GetEnumerator(); } private void AddElement(TKey a_key, TElement a_element) { List<TElement> list; if (!_dicLookup.TryGetValue(a_key, out list)) { list = new List<TElement>(); _dicLookup.Add(a_key, list); } list.Add(a_element); } private IEnumerable<IGrouping<TKey, TElement>> GetGroupings() { return from key in _dicLookup.Keys select new LookupDictionaryGrouping<TKey, TElement> { Key = key, Elements = _dicLookup[key] } as IGrouping<TKey, TElement>; } } public class LookupDictionaryGrouping<TKey, TElement> : IGrouping<TKey, TElement> { public TKey Key { get; set; } public IEnumerable<TElement> Elements { get; set; } public IEnumerator<TElement> GetEnumerator() { return Elements.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return (Elements as System.Collections.IEnumerable).GetEnumerator(); } } 
+4
source

As mentioned in mquander, the search is unchanged. However, you can create a new search with additional or deleted values.

 // Add a new value myLookup = myLookup .SelectMany(l => l.Select(v => new {l.Key, Value = v})) .Union(new[] {new {Key = myNewKey, Value = myNewValue}}) .ToLookup(a => a.Key, a => a.Value); // Remove an old value myLookup = myLookup .SelectMany(l => l.Select(v => new {l.Key, Value = v})) .Where(a => a.Value != myOldValue) .ToLookup(a => a.Key, a => a.Value); 
0
source

All Articles