Reputation: 2901
I have a list (HashSet actually) of a class that contains 2 other lists. Here's a mockup with example data:
public class Example
{
public Example(HashSet<int> a, HashSet<int> b)
{
ListA = a;
ListB = b;
}
public HashSet<int> ListA { get; set; }
public HashSet<int> ListB { get; set; }
}
public class UseCase
{
public UseCase()
{
var hs = new HashSet<Example>();
hs.Add(new Example(new HashSet<int> { 1}, new HashSet<int> { 100, 200 }));
hs.Add(new Example(new HashSet<int> { 2,3,4,5 }, new HashSet<int> { 100, 200, 300 }));
hs.Add(new Example(new HashSet<int> { 6,9,12 }, new HashSet<int> { 200, 300 }));
}
}
Here are the rules for the two lists:
List A contains only unique numbers - they are never repeated, either within their own HashSet or any other ListA HashSet.
List B contains numbers that are unique within their own HashSet, but they may be repeated in one or more List B HashSet.
What I'm trying to do is return all numbers in matching ListA rows, where a specific number exists in ListB.
Here's a mockup linq query:
public static IEnumerable<int> GetDistinctFromListA(int b)
{
return UsesCases
.Where(x => x.ListB.Contains(b))
}
So, at this point I have a number of rows, but I now need to extract all numbers from matching ListB lists. If the parameter entered was 100, then I would expect to return a list containing the numbers 1, 2, 3, 4 and 5.
I've been playing around with All and SelectMany but can't seem to get the result I need.
Upvotes: 0
Views: 1054
Reputation: 51633
public class Example
{
public Example(HashSet<int> a, HashSet<int> b)
{
ListA = a;
ListB = b;
}
public HashSet<int> ListA { get; set; }
public HashSet<int> ListB { get; set; }
}
static IEnumerable<int> GetDistinctFromListA(HashSet<Example> hs, int b)
{
var rv = hs.Aggregate(new HashSet<int>(), (acc, el) =>
{
if (el.ListB.Contains(b)) acc.UnionWith(el.ListA);
return acc;
});
return rv;
}
static void Main(string[] args)
{
var hs = new HashSet<Example>();
hs.Add(new Example(new HashSet<int> { 1 }, new HashSet<int> { 100, 200 }));
hs.Add(new Example(new HashSet<int> { 2, 3, 4, 5 }, new HashSet<int> { 100, 200, 300 }));
hs.Add(new Example(new HashSet<int> { 6, 9, 12 }, new HashSet<int> { 200, 300 }));
foreach (var b in hs.SelectMany(e => e.ListB).Distinct())
Console.WriteLine($"{b} => {string.Join(",", GetDistinctFromListA(hs, b))}");
Console.ReadLine();
}
This goes through all Elements of hs, checks each elements ListB if it contains b and if so adds its ListA elements to the result.
If you compare only Hashsets without depending on other Hashsets you can use Intersect / Union / Except etc. (set theory stuff).
Upvotes: 2
Reputation: 5745
A HashSet
is meant to contain only unique values and this is to say that all queries you make inherently return distinct values. If you want to find the intersection between two HashSet
you can call the Intersect
method.
For example:
//The additional 1 is ignored here
HashSet<int> A = new HashSet<int> { 1, 1, 2, 3, 4, 5 };
HashSet<int> B = new HashSet<int> { 1, 5, 8, 9 };
var Result = A.Intersect(B);
Upvotes: 1
Reputation: 1327
I think you want to return the intersection of 2 sets
There is a Linq function that does this
var commonInBoth = List1.Intersect(List2);
Upvotes: 0