19

I'm using Lookup class in C# as my prime data container for the user to select values from two Checked List boxes.

The Lookup class is far easier to use than using the class Dictionary>, however I cannot find methods for removing and adding values to a lookup class.

I thought about using the where and the union, but i cant seem to get it right.

Thanks in advance.

Ahmad Hajou
  • 1,289
  • 5
  • 22
  • 39
  • 1
    Why dont you create youre own Lookup implementation? Basing it on a Dictionary, should not take more than a few lines of code. – leppie Oct 27 '10 at 08:13
  • Kind of agree with leppie here. The lookup class is there to only lookup data, not modify it. Plus the dictionary isn't too hard to use anyway, might be nice just to write a wrapper on top of a dictionary. – Ray Booysen Oct 27 '10 at 08:57
  • The lookup also has a different mechanism to do the actual lookups over a dictionary. But with some simple tests, they both perform very quickly. – Ray Booysen Oct 27 '10 at 09:01
  • I found it easier to use lookup than use Dictionary>, but i guess writing my own wrapper will make things easier. – Ahmad Hajou Oct 27 '10 at 12:45
  • @ Leppie the Idea of creating your own structure is good but a dictionary is incompatible with a lookup as a lookup specifically allows multiple keys with the same value, a list of Tuples would be better – MikeT Sep 30 '13 at 16:14

2 Answers2

20

Unfortunately the creation of the Lookup class is internal to the .NET framework. The way that the lookup is created, is via static Factory Methods on the Lookup class. These are:

internal static Lookup<TKey, TElement> Create<TSource>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer);
    internal static Lookup<TKey, TElement> CreateForJoin(IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IEqualityComparer<TKey> comparer);

However, these methods are internal and not for consumption by us. The lookup class does not have any way of removing items.

One way you could do an add and remove is to constantly create new ILookups. For example - how to delete an element.

public class MyClass
{
  public string Key { get; set; }
  public string Value { get; set; }
}

//We have a fully populated set:
var set = new List<MyClass>() //Populate this.
var lookup = set.ToLookup(m => m.Key, m => m);

//Remove the item where the key == "KEY";
//Now you can do something like that, modify to your taste.
lookup = lookup
  .Where(l => !String.Equals(l.Key, "KEY"))
   //This just flattens the set - up to you how you want to accomplish this
  .SelectMany(l => l)
  .ToLookup(l => l.Key, l => l.Value);

For adding to the list, we could do something like this:

//We have a fully populated set:
var set = new List<MyClass>() //Populate this.
var lookup = set.ToLookup(m => m.Key, m => m);

var item = new MyClass { Key = "KEY1", Value = "VALUE2" };

//Now let's "add" to the collection creating a new lookup
lookup = lookup
  .SelectMany(l => l)
  .Concat(new[] { item })
  .ToLookup(l => l.Key, l => l.Value);
Ray Booysen
  • 28,894
  • 13
  • 84
  • 111
2

what you can do instead of using a LookUp class is to simply use this

var dictionary = new Dictionary<string, List<A>>(); 

where A is the object type you want to map to the key. i trust you know how to add and delete the group of matched objects to a specific key. :)

eva
  • 89
  • 1
  • 2
  • Thanks. The .net Lookup class is pretty useless in my opinion because it's not mutable. – Jason Cheng Apr 18 '19 at 19:31
  • 1
    @JasonCheng - Lookup tables offer a significant performance gain on query operations, even when compared to hash tables (Dictionary). Both approaches have comparable performance during creation/indexing. So, in any scenario where you're going to be doing more querying than mutation, or indexing on multiple keys, a Lookup is very useful. – Dave Jellison Jul 26 '19 at 18:14
  • 1
    Lookup also has the advantage of unregistered keys returning empty collections instead of KeyNotFoundException or a null reference. Therefore, it is always safe to foreach over collections associated to candidate keys. Much simpler code. – Tormod Jun 11 '20 at 08:08
  • Be aware that `LookUp` - in contrast to `Dicitonary` allows for duplicate keys. – MakePeaceGreatAgain Aug 22 '23 at 08:45