先进的LINQ过滤

时间:2019-05-10 10:40:35

标签: c# performance linq collections

我对使用LINQ进行高级过滤数据有疑问。

我想获得带有详细信息列表的计划类的列表,其中“项目列表”中的参数包含特定字符。此外,“项目”列表应仅包含此过滤后的元素。

我的课程如下所示:

class Plan
{
    public string Name { get; set; }
    public List<Detail> Details { get; set; }

    public Plan()
    {
        Details = new List<Detail>();
    }
}

class Detail
{
    public string Setting { get; set; }

    public List<Item> Items { get; set; }

    public Detail()
    {
        Items = new List<Item>();
    }
}

class Item
{
    public string Arguments { get; set; }
}

我当前的解决方案如下所示,但我认为这不是最佳选择。我尝试使用WhereAny编写此代码,但是我有“计划”列表,其中“项目”包含所有项目。

var filteredPlans = plans.Select(x =>
            new Plan
            {
                Name = x.Name,
                Details = x.Details.Select(y =>
                    new Detail
                    {
                        Setting = y.Setting,
                        Items = y.Items.Where(c => c.Arguments.Contains("...")).Select(z =>
                              new Item
                              {
                                  Arguments = z.Arguments
                              }).ToList()
                    }).ToList()
            });

如何使用WHERE语句编写此代码,或者什么是最佳解决方案?

我还如何使用基于项目列表的LINQ EXPECT获得收成差异?例如计划:包含所有带有项目的计划,计划2:包含带有过滤项目的所有计划,并且计划3应该包含带有不属于计划2的项目的所有计划。

1 个答案:

答案 0 :(得分:1)

这对您有用吗?

首先,我只限于计划的任何详细信息包含与过滤器匹配的任何项目。

然后,我将每个计划的详细信息限制为仅包含与过滤器匹配的任何项目的计划

然后我限制每个计划的项目

    private List<Plan> FilteredPlans(List<Plan> plans, string filter)
    {
        List<Plan> filteredPlans = plans.Where(plan => plan.Details.Any(detail => detail.Items.Any(item => item.Arguments.Contains(filter)))).ToList();

        foreach (var plan in filteredPlans)
        {
            plan.Details = plan.Details.Where(detail => detail.Items.Any(item => item.Arguments.Contains(filter))).ToList();

            foreach (var detail in plan.Details)
            {
                detail.Items = detail.Items.Where(item => item.Arguments.Contains(filter)).ToList();
            }
        }

        return filteredPlans;
    }

此外,这是一个声明的另一个版本,但我认为它的可读性要差得多。我基本上是先限制项目,然后再往回走,只保留不为空的容器

    private List<Plan> FilteredPlansWithSelect(List<Plan> plans, string filter)
    {
        List<Plan> filteredPlans = plans.Select(plan => 
        new Plan()
        {
            Name = plan.Name,
            Details = plan.Details.Select(detail =>
                new Detail()
                {
                    Setting = detail.Setting,
                    Items = detail.Items.Where(item => item.Arguments.Contains(filter)).ToList()
                }).Where(detail => detail.Items.Count > 0).ToList()
        }).Where(plan => plan.Details.Count > 0).ToList();


        return filteredPlans;
    }

针对语法编辑