C#根据列表中匹配的数据从子列表中获取值

时间:2019-12-02 19:49:39

标签: c# list linq

我遇到这样的情况:我有一个包含另一个列表的列表,并且有一个在两个级别上都匹配的字符串,并且仅从两个列表中返回匹配的值。

例如: 类别:“ A”包含产品“ A”,“ B”和“ AA” 类别:“ B”包含产品“ BA”,“ C”和“ D” 类别:“”包含产品“ A”,“ B”

如果我的输入参数为A,则结果应为: 类别“ A”与产品“ A”和“ AA” 产品类别为“ A”的产品为“ A”

如果我的输入是B,则结果应为: 类别“ B”和产品“ BA” 类别“”和产品“ B”

到目前为止,我所做的是:

 result = AllCustomListValues.
                         Where(c => c.CategoryName.ToLower().Contains(searchTextInput.ToLower())
                         || c.CategoryName == ""
                         ).ToList();

            foreach (var value in result)
            {
                if (value.CategoryName == "")
                {
                    foreach (var CustomList in value.CustomLists)
                    {
                        if (!CustomList.ListName.ToLower().Contains(searchTextInput.ToLower()))
                            CustomListToRemove.Add(CustomList);
                    }
                    foreach (var ListToRemove in CustomListToRemove)
                        value.CustomLists.Remove(ListToRemove);
                }
            }

在这里,AllCustomListValues包含整个数据,即包含子列表的列表(包含自定义列表的类别列表)。我在类别级别匹配输入文本字符串,然后获取第一组匹配的类别,在第二级别,我试图获取与输入文本字符串不匹配的自定义列表数据,然后添加然后从中删除主要类别列表的子列表,即“自定义列表”,这一切工作正常,但似乎非常详尽且刻板,我正在寻找一个更简单,更灵活的选项。

1 个答案:

答案 0 :(得分:0)

我不确定您为什么在第二级上做if (value.CategoryName == ""),所以我跳过了它(随时添加)。 我还相信通过删除子项,您正在突变您不希望使用的AllCustomListValues变量。

您可能会尝试以下方法:

searchTextInput = searchTextInput.ToLower(); // just so we only do it once.
AllCustomListValues.SelectMany(cat => cat.CustomLists, (cat, product) => new { cat.CategoryName, product.ListName, product}) // basically we flatten the Product structure and expose properties to search and rebuild our list later 
.Where(c => c.CategoryName.ToLower().Contains(searchTextInput) || c.CategoryName == "" || c.ListName.ToLower().Contains(searchTextInput)) // apply your filters here to both Category and Filter
.GroupBy(i => i.CategoryName) // reconstructing your hierarchy
.Select(g => new Category {CategoryName = g.Key, CustomLists = g.Select(p => p.product).ToList() } )
.ToList();