代码之家  ›  专栏  ›  技术社区  ›  Superman.Lopez

筛选对象列表,其中嵌套集合与数组匹配

  •  2
  • Superman.Lopez  · 技术社区  · 6 年前

    我有一个物品清单( items )我要根据嵌套集合的值筛选( Features 在宾语中 GenericItem )作为过滤器的基础,我有一个int数组( filter )我的目标是找到 项目 何处 特征 收藏包括 至少所有值 滤波器 数组。

    以下是我在StackOverflow上为其他人提供的许多解决方案。我遇到的问题是,在我的LINQ查询(以及我尝试过的许多变体)中,我最终总是将所有对象都放入 项目 哪里都 特征 包含在 滤波器 . 我理解lambda表达式是“错误的顺序”,但是,因为我最终希望得到一个 通用项 我好像不知道怎么写我的表情。

    如何编写LINQ表达式以获得预期的结果?

    所以在下面,当我过滤 [2, 3] 我的目标是 result 保持“项目A”和“项目B”(两者至少具有特征2和3)。相反,我得到 结果 “B项”和“C项”的 全部的 他们的 特征 包括在 滤波器 数组。

    public class GenericItem {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Feature> Features { get; set; }
    }
    
    public class Feature {
        public int Id { get; set; }
    }
    
    static void Main (string[] args) {
    
        var items = new List<GenericItem>();
        items.Add(new GenericItem() {
            Id = 1,
            Name = "Item A",
            Features = new Collection<Feature>() { 
                new Feature() {Id = 1},      
                new Feature() {Id = 2},      
                new Feature() {Id = 3}
            }      
        });
        items.Add(new GenericItem() {
            Id = 2,
            Name = "Item B",
            Features = new Collection<Feature>() {     
                new Feature() {Id = 2},      
                new Feature() {Id = 3}
            }      
        });
        items.Add(new GenericItem() {
            Id = 3,
            Name = "Item C",
            Features = new Collection<Feature>() {    
                new Feature() {Id = 3}
            }
        });
    
        int[] filter = new int[] {2, 3};
    
        var resultAll = items.Where(i => i.Features.All(f => filter.Contains(f.Id)));
    
        foreach (GenericItem I in resultAll)
            System.Console.WriteLine(I.Name);
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Ousmane D.    6 年前

    应用 All filter 集合而不是 i.Features :

    var resultAll = items.Where(i => filter.All(x => i.Features.Any(f => x == f.Id)));