如何使用Linq过滤嵌套列表?

时间:2012-01-23 05:03:54

标签: linq linq-to-objects

我在这样的Dictionary<string, IList<ID>>上使用LINQ:

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();

这将返回A类,B类或C类中的所有ID。但我想要检索的是类别A,B和C中的ID。

我很难找到如何使用Linq做到这一点。

更新

对不起,我应该在我的帖子中添加更多信息。我的字典中的列表看起来有点像这样(我这里只使用数字来简化):

答:{1,2,3} B:{1,3}
C:{3}

因此,在我的查询中,我想要的是“3”,因为它是唯一包含所有类别的数字。

3 个答案:

答案 0 :(得分:1)

看起来你只是占据了所有列表的交集。这应该很容易获得。

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));

如果您的ID类型没有实现IEquatable<ID>接口,那么您可能需要提供一个相等比较器(我假设您有)来执行比较。

 ....Aggregate((acc, cur) => acc.Intersect(cur, new YourIdEqualityComparer()));

答案 1 :(得分:0)

您可以尝试将x => searchCategories.Contains(x.Key)更改为x => searchCategories.All(c => x.Key.Contains(c)),即最终的代码段应为

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();

答案 2 :(得分:0)

要获得所有ID,SelectMany方法非常适用于此:

var ids = CategoryMapper.Mapping.SelectMany(kv => kv.Value);