Reputation: 3865
I use LINQ on a Dictionary<string, IList<ID>>
like this:
var searchCategories = new List {"A", "B", "C"};
Result = CategoryMapper.Mapping.Where(
x => searchCategories.Contains(x.Key)).
Select(x => new Tuple<string, IList<ID>>(x.Key, x.Value)).ToList();
This returns all ids that are either in Category A, B or C. However what I would like to do is retrieve ids that are in Category A, B and C.
I'm having difficulties figuring out how to do this with Linq.
UPDATE
I'm sorry but I should have added some more information in my initial post. The lists in my dictionary look somewhat like this (I only use numbers here to make it simple):
A : {1, 2, 3}
B : {1,3}
C : {3}
So what I would like as a result of my query would be '3' in this case because it is the only number that has all categories.
Upvotes: 1
Views: 1692
Reputation: 134811
Looks like you're just taking the intersection of all the lists. That should be simple to obtain.
var searchCategories = new HashSet<string> { "A", "B", "C" };
var result = CategoryMapper.Mapping
.Where(map => searchCategories.Contains(map.Key))
.Select(map => map.Value as IEnumerable<ID>)
.Aggregate((acc, cur) => acc.Intersect(cur));
If your ID
type doesn't implement the IEquatable<ID>
interface, then you may need to provide an equality comparer (that I assume you have) to perform the comparisons.
....Aggregate((acc, cur) => acc.Intersect(cur, new YourIdEqualityComparer()));
Upvotes: 1
Reputation: 15810
To get all the ids, the SelectMany
method is perfect for this:
var ids = CategoryMapper.Mapping.SelectMany(kv => kv.Value);
Upvotes: 0
Reputation: 1634
You can try to change x => searchCategories.Contains(x.Key)
to x => searchCategories.All(c => x.Key.Contains(c))
, i.e. the final code snippet should be
var searchCategories = new List<string> {"A", "B", "C"};
Result = CategoryMapper.Mapping.Where(
x => searchCategories.All(c => x.Key.Contains(c))).
Select(x => new Tuple<string, IList<ID>>(x.Key, x.Value)).ToList();
Upvotes: 0