Home > Mobile >  Intersect on HashSet results in compile error
Intersect on HashSet results in compile error

Time:01-30

I've been trying to write a program, in which I want to use the intersection of two HashSets. Therefore I wrote the following code (for test purposes):

HashSet<int> test1 = new HashSet<int>() { 1, 3, 5, 7, 9 };
HashSet<int> test2 = new HashSet<int>() { 1, 2, 3, 4, 5, 6};
HashSet<int> intersect = new HashSet<int>();
intersect = test1.Intersect(test2);

Line 5 shows an error (code CS0266) which - that's C#'s suggestion - can be corrected by change the line to: intersect = (HashSet<int>)test1.Intersect(test2); But when I run the program, the error appears again. I literally have no clue why, even after searching for an answer. I want to achieve a intersection in the mathematical sense, so that the result for the variable intersect should be { 1, 3, 5}. And what I found out - but couldn't test - is, that after using the intersect-method on test1, it changes the list in test1 to the intersection, is that true? If yes, is there any chance to avoid this? In my real program I don't want the variable to change into the intersection.

Should I just make a for-loop with an if-statement, to make my own intersection-method, or does this make the code worse?

As said, I tried to make use of C#'s suggestion, but this doesn't work either. Because I'm a programming-beginner, I'm not really able to understand the definition of the intersect-method (because of this IEnumerable thing...), so I can't solve the problem using existend methods. And because I think my own method could be very inefficient, I don't to it my own. Furthermore I just want to understand, what's the problem. There are two HashSets, both containing integers, which should be intersected and saved in an extra variable...

CodePudding user response:

Enumerable.Intersect is a LINQ extension method that works with any kind of IEnumerable<T>. It returns IEnumerable<T>, so not a HashSet<T>. But since you have alrady two sets you want to use HashSet.IntersectWith(more efficient since O(n)) with manipulates the first HashSet<T>:

test1.IntersectWith(test2); // test1 contains now [1, 3, 5]

CodePudding user response:

Intersect() returns a IEnumerable<T>. You can use IntersectWith(), which modifies the current HashSet<T> object to contain only elements that are present in that object and in the specified collection:

HashSet<int> test1 = new HashSet<int>() { 1, 3, 5, 7, 9 };
HashSet<int> test2 = new HashSet<int>() { 1, 2, 3, 4, 5, 6};
test1.IntersectWith(test2); // we are altering test1 here
// test1 contains now [1, 3, 5]

or use the side-effect free Linq Intersect() to get an IEnumerable<T> and if you want it to be a new HashSet<T> just use a constructor:

HashSet<int> test1 = new HashSet<int>() { 1, 3, 5, 7, 9 };
HashSet<int> test2 = new HashSet<int>() { 1, 2, 3, 4, 5, 6};
HashSet<int> intersect = new HashSet<int>(test1.Intersect(test2));
// intersect contains now [1, 3, 5]

Remarks (from MSDN)

If the collection represented by the other parameter is a HashSet<T> collection with the same equality comparer as the current HashSet<T> object, this method is an O(n) operation. Otherwise, this method is an O(n m) operation, where n is Count and m is the number of elements in other.

Basically in your case IntersectWith() is going to be more efficient!

Complete demo:

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        HashSet<int> test1 = new HashSet<int>() {1, 3, 5, 7, 9};
        HashSet<int> test2 = new HashSet<int>() {1, 2, 3, 4, 5, 6};
        HashSet<int> intersect = new HashSet<int>(test1.Intersect(test2));
        intersect.Dump();
        test1.IntersectWith(test2);
        test1.Dump();
    }
}

Try it Online!

  • Related