Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersect on HashSet results in compile error

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...

like image 784
Lisa Avatar asked Mar 15 '26 15:03

Lisa


2 Answers

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!

like image 69
aloisdg Avatar answered Mar 18 '26 03:03

aloisdg


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]
like image 40
Tim Schmelter Avatar answered Mar 18 '26 05:03

Tim Schmelter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!