Skip to content

EditableLookup

kobi2294 edited this page Apr 18, 2019 · 2 revisions

Editable Lookup class

An editable implementation of the ILookup<K, T> class. The ILookup Interface defines mapping between keys and values where each key may have a group of values (as opposed to dictionaries where each key is mapped to a single value). C# Defines the ILookup interface but does not provide an editable class that supports it. This class aims to fill this gap.

Querying

  • Use the Contains method to check if a key exists.
  • Use the ContainsPair method to check if a specific key-value pair exists.
  • Use the Count property to get the number of keys (groups) in the lookup.
  • Use the Indexer property this[K key] to get the IEnumerable of values for a specific key.
  • Use the Keys property to get an enumerable of all the keys.

Adding items

  • Use the Add(K key, T value) method to add a specific key-value pair.
  • Use the Reset(K key, IEnumerable<T> values) method to set all the values for a specific key.

Note that all methods that add new values, will also create the key if it does not already exist.

Removing items

  • Use the Remove(K key, T value) method to remove a specific pair.
  • Use the RemoveKey(K key) method to remove a key and all it's values.
  • Use the RemoveWhere(K key, Predicate<T> predicate) to selectivly remove multiple values of specific key.
  • Use the Clear method to remove all keys and values.

Note that all methods that remove values, will also remove the key if it no longer has any values.

Enumerable

The class also implements the ILookup<K, T> interface, which means it is an enumerable of IGrouping<K, T> so you can iterate over the groups of values.

Extension methods

Use the ToEditableLookup method to convert from the followings to an editable lookup:

  • IEnumerable<IGrouping<K, T>>
  • IEnumerable<(K, T)>
  • IDictionary<K, List<T>>
  • IDictionary<K, IEnumerable<T>>
  • IEnumerable<T> (using a key selector)
  • IEnumerable<OTHER> (using key selector and value selector)

Example

            // create an enumerable of pairs in the format (5, (a:2, b:3))
            var pairs = from a in Enumerable.Range(1, 10)
                        from b in Enumerable.Range(1, 10)
                        where a <= b
                        select (a + b, (a:a, b:b));

            var el = pairs.ToEditableLookup();
            var keys = el.Keys;

            Console.WriteLine($"There are {keys.Count()} keys: ");  // 19 keys
            Console.WriteLine(string.Join(", ", keys)); // from 2 to 20

            Console.WriteLine($"For example, the key 14 has the following values: ");

            // 4 + 10, 5 + 9, 6 + 8, 7 + 7
            Console.WriteLine(string.Join(", ", el[14].Select(pair => $"{pair.a} + {pair.b}")));

            Console.WriteLine("Now we move all values where a == b");
            el.RemoveWhere(14, pair => pair.a == pair.b);

            // 4 + 10, 5 + 9, 6 + 8
            Console.WriteLine(string.Join(", ", el[14].Select(pair => $"{pair.a} + {pair.b}")));