1

I am using a HashSet of List elements in C#. However, it doesn't get rid of duplicate List elements.

HashSet<List<int>> set = new HashSet<List<int>>();
List<int> l1 = new List<int>() { 1, 2 };
List<int> l2 = new List<int>() { 1, 2 };
set.Add(l1);
set.Add(l2);
foreach (List<int> l in set) {
    foreach(int i in l) {
        Console.Write(i + " ");
    }
    Console.WriteLine();
}

The output is as follows:

1 2
1 2

However, I want the output to be just:

1 2

How do I do that?

1 Answers1

2

You need to provide a custom IEqualityComparer<List<int>> implementation that checks the contents of the lists.

public class ListEqualityComparer : IEqualityComparer<List<int>>
{
    public bool Equals(List<int> x, List<int> y)
    {
        if (x is null && y is null)
        {
            return true;
        }
        else if (x is null || y is null)
        {
            return false;
        }
        
        if (x.Count != y.Count)
        {
            return false;
        }
        
        return x.SequenceEqual(y);
    }

    // taken from https://stackoverflow.com/a/8094931/1165998
    public int GetHashCode(List<int> obj)
    {
        unchecked
        {
            int hash = 19;
            foreach (var item in obj)
            {
                hash = hash * 31 + item.GetHashCode();
            }
            return hash;
        }
    }
}

When used with your example, it produces only one set of 1 2 results:

HashSet<List<int>> set = new HashSet<List<int>>(new ListEqualityComparer());
List<int> l1 = new List<int>() { 1, 2 };
List<int> l2 = new List<int>() { 1, 2 };
set.Add(l1);
set.Add(l2);
foreach (List<int> l in set)
{
    foreach (int i in l)
    {
        Console.Write(i + " ");
    }
    Console.WriteLine();
}
David L
  • 32,885
  • 8
  • 62
  • 93