【问题标题】:Select items from a List where the children contain the items from another List using LINQ使用 LINQ 从列表中选择项目,其中子项包含来自另一个列表的项目
【发布时间】:2013-07-06 17:44:53
【问题描述】:

我有以下课程:

产品:

public class Product
{
    public string Name { get; set; }
    public List<Category> Categories { get; set; }
}

类别:

public class Category
{
    public string Id { get; set; }
    public string Name { get; set; }
}

我有以下方法:

public List<Product> FilterProducts(List<Category> categories)
{
    // filtering code here
}

问题:如何使用List&lt;Categories&gt; 作为参数过滤我的产品?

编辑:我忘了提一件事,如果我有 2 个类别,我应该只能看到具有 category1 AND 的产品强> category2。到目前为止,我所做的只返回了 category1 或 category2 的产品。虽然继承 IEquatable 使用 Intersect 似乎很有趣,但我现在正在与 Id 进行比较。

【问题讨论】:

  • 我会成为那个人......到目前为止你尝试了什么?
  • (来自 Products.Any(p => categories.Contains(p.Category) 中的产品)
  • 刚刚编辑并仍在测试:)
  • 如果您需要“仅查看类别 1 和类别 2 的产品”。那么你将需要我的第一个解决方案,它使用All 方法。以下是如何使用 Id 进行重写:return products.Where(p =&gt; categories.All(c =&gt; p.Categories.Any(cat =&gt; cat.Id == c.Id)).ToList()

标签: c# linq


【解决方案1】:

如果您想退回所有在其Categories 中具有所有提供的类别的产品,这意味着它会选择具有类别 1 和类别 2 的产品。

那么你需要使用AllContains的组合:

public List<Product> FilterProducts(List<Category> categories)
{
    return products.Where(p => categories.All(c => p.Categories.Contains(c))
                   .ToList();
}

如果您想从提供的类别中返回它至少有一个类别的所有产品,这意味着它会选择它具有类别 1 或类别 2 的产品。

那么你需要使用Any

public List<Product> FilterProducts(List<Category> categories)
{
    return products.Where(p => categories.Any(c => p.Categories.Contains(c)
                   .ToList();
}

请注意,如果您的categories 对象与您在产品的Categories 属性或Category 中的实例不同,则您没有覆盖Equals 方法以使用Id您可能想要比较 Ids 而不是类别对象本身。

比如:

全部

的解决方案
public List<Product> FilterProducts(List<Category> categories)
{
     return products.Where(p => categories
        .All(c => p.Categories.Any(cat => cat.Id == c.Id)).ToList()
}

任何的解决方案

public List<Product> FilterProducts(List<Category> categories)
{
    return products.Where(p => categories
        .Any(cat => p.Categories.Any(pcat => pcat.Id == cat.Id)).ToList();
}

【讨论】:

  • 我想一定是Anyone
  • 请注意,您的使用情况可能会有所不同。如果这两个类别在语义上是相同的,但来自不同的来源(即它们不是同一个引用),那么这个版本的 Contains 是无用的(正如我们看到的 Category 没有实现 IEquatable 或覆盖哈希码 /等于方法)。如果是这种情况,您可能想在 Id 上使用 lambda 进行比较。
  • 当您声明的返回类型为 List&lt;&gt; 时,您不能返回惰性 Linq 迭代器。
  • 完美!非常感谢!
  • 我正在使用 List 就像你在你的例子中一样,但是,没有 Where 方法并给出编译错误。我正在使用 VS 2015。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-07
  • 2012-06-30
相关资源
最近更新 更多