0

If I have a Dictionary<int[], int>, which contains 2 entries

{1, 2, 3} , 1 and
{4, 5, 6} , 2

How do I check whether the dictionary contains the key {1, 2, 3}? If i do:

if (dictionary.ContainsKey(new int[] {1,2,3})
{
  // do things
}

It will not return the correct result as the created array is different from the key array. I know you can override the Equals method for a custom class, but is there another way to check if a dictionary which has an array as the key, contains an entry whose key array has the same values within it as the comparison array?

Cirrus86
  • 336
  • 4
  • 13
  • 1
    Too quick to be an answer, but as a hint : you can create a custom comparer, or instead use a custom class that implements `IEquatable` for the key type – Pac0 Jul 28 '20 at 07:30
  • Do all of your arrays have three elements? In that case you could use tuples: `Dictionary<(int,int,int),int>` – SomeBody Jul 28 '20 at 07:49
  • 1
    Keep in mind that even if you implement it in the way referenced in the duplicate there can be weird results. Imagine what would happen in the following scenario, we have `var a = new int[] {1, 2, 3};` now we add an entry to our dictionary `dict.Add(a, 5);` afterwards somebody does `a[2] = 10;` now the content of the referenced object changed but this is only reflected in the equality check and not in the used hashcode creating a "corrupt" entry. –  Jul 28 '20 at 07:55

3 Answers3

3

As quick workaround, you can use SequenceEqual and Any methods. It'll work, if you need a value comparison only

if (dictionary.Keys.Any(key => key.SequenceEqual(new [] {1, 2, 3})))
{
}
Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
3

Well, arrays are compared by reference so we have

int[] a = new int[] {1, 2, 3};

int[] b = new int[] {1, 2, 3}; // same content, different reference

// Prints "No"
Console.WriteLine(a.Equals(b) ? "Yes" : "No");

Dictionary<int[], string> dict = new Dictionary<int[], string>() {{
  a, "Some Value"}};

// Prints "Not Found"
Console.WriteLine(dict.TryGetValue(b, out var value) ? value : "Not Found");

So we have to explain .Net how to compare arrays; we can do it with a comparer:

public class SequenceEqualityComparer<T> : IEqualityComparer<IEnumerable<T>> {
  public bool Equals(IEnumerable<T> x, IEnumerable<T> y) {
    if (ReferenceEquals(x, y))
      return true;
    else if (null == x || null == y)
      return false;

    return Enumerable.SequenceEqual(x, y, EqualityComparer<T>.Default); 
  }

  public int GetHashCode(IEnumerable<T> obj) =>
    obj == null ? 0 : obj.FirstOrDefault()?.GetHashCode() ?? 0;
}

And we should declare the dictionary while mentioning the comparer:

Dictionary<int[], string> dict = 
  new Dictionary<int[], string>(new SequenceEqualityComparer<int>()) {
    {a, "Some Value"}};

Now we can do business as usual:

// Returns "Some Value" 
Console.WriteLine(dict[b]);
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
-1

You can try,

if (dictionary.Any(x => Enumerable.SequenceEqual(new int[] { 1, 2, 3 }, x.Key)))
    Console.WriteLine("There is exists one.");

Note : Method using System.Linq Library.