Расширенная фильтрация LINQ - PullRequest
1 голос
/ 10 мая 2019

У меня проблема с расширенной фильтрацией данных с использованием LINQ.

Я хотел бы получить список классов Plan с подробным списком, где аргументы в списках элементов содержат определенные символы.Также список предметов должен содержать только эти отфильтрованные элементы.

Мои классы выглядят так:

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

Мое текущее решение выглядит так, но я думаю, что это не лучший вариант.Я пытался написать этот код, используя Where и Any, но у меня есть список планов, в котором элементы содержат все элементы.

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 Ответ

1 голос
/ 10 мая 2019

Это у вас работает?

Сначала я ограничиваюсь только планами, в которых любая их информация содержит какой-либо элемент, соответствующий фильтру.

Затем я ограничиваю детали для каждого плана только теми, у кого есть какой-либо элемент, соответствующий фильтру

Тогда я ограничу количество пунктов для каждого плана

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

Отредактировано для грамматики

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...