Click here to Skip to main content
15,885,278 members
Articles / Programming Languages / C#
Tip/Trick

Using Collections as Keys in C#

Rate me:
Please Sign up or sign in to vote.
3.05/5 (5 votes)
9 Feb 2020MIT 9.6K   86   5   3
Using IEqualityComparer to allow collections to be keys in dictionaries and hashsets
Using collections as keys allows for complex functional constructs to be expressed in C# more easily. This code provides two classes for doing ordered or unordered equality comparisons on collections so that they may be used as keys in dictionaries and sets.

Introduction

Sometimes when expressing complicated algorithms in C# you may find yourself needing to look up some information based on a set of items rather than a single item. Stock .NET provides a little bit of functionality for doing this via LINQ but it's not generalized such that Dictionary<TKey,TValue> for example can use it.

This little library aims to provide two styles of comparison so that these types of operations are easy.

Using this Mess

A Cautionary Note

Keys should not be mutable, but because of how collections work these ones are mutable when they shouldn't be. Do not modify collections you are using as keys! It will cause you nasty bugs.

 

This library exposes two classes, OrderedCollectionEqualityComparer<T> and UnorderedCollectionEqualityComparer<T>, which provides ordered and unordered comparisons respectively. They work on anything implementing IList<T>, ICollection<T>, or ISet<T>. Unordered comparisons can be expensive, but using HashSet<T> for your collections can speed that up some. You can use these classes to provide Dictionary<TKey, TValue> and HashSet<TKey, TValue> with a way to compare collections instead of single items. The demo code indicates how to use them:

C#
// create a new hashset that uses ordered collection comparisons
var set = new HashSet<int[]>(OrderedCollectionEqualityComparer<int>.Default);
// add a collection:
set.Add(new int[] { 1, 2, 3, 4, 5 });

// true:
Console.WriteLine("Ordered cmp - contains 1-5: " + set.Contains(new int[] { 1, 2, 3, 4, 5 }));
// false:
Console.WriteLine("Ordered cmp contains 5-1: " + set.Contains(new int[] { 5, 4, 3, 2, 1 }));

// create a new hashset that uses unordered collection comparisons
set = new HashSet<int[]>(UnorderedCollectionEqualityComparer<int>.Default);
set.Add(new int[] { 1, 2, 3, 4, 5 });

// true:
Console.WriteLine("Unordered cmp - contains 1-5: " + set.Contains(new int[] { 1, 2, 3, 4, 5 }));
// true:
Console.WriteLine("Unordered cmp contains 5-1: " + set.Contains(new int[] { 5, 4, 3, 2, 1 }));

 

History

  • 9th February, 2020 - Initial submission

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
United States United States
Just a shiny lil monster. Casts spells in C++. Mostly harmless.

Comments and Discussions

 
QuestionI may be missing something.. Pin
kaos_12117-Feb-20 18:49
professionalkaos_12117-Feb-20 18:49 
QuestionCaution Pin
wkempf10-Feb-20 4:12
wkempf10-Feb-20 4:12 
AnswerRe: Caution Pin
honey the codewitch10-Feb-20 4:54
mvahoney the codewitch10-Feb-20 4:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.