Как подготовить данные для всех приложений сразу без цикла для каждого приложения?

#c#

#c#

Вопрос:

У меня есть один основной список из 2 фильтров, и это связано с одним приложением,

 var filterData = new List<FilterData>
            {
                new FilterData { Filter1 = "test1", Filter2 = "X", GoesToApp = "App1"},
                new FilterData { Filter1 = "test2", Filter2 = "X", GoesToApp = "App2"},
                new FilterData { Filter1 = "test2", Filter2 = "Y", GoesToApp = "App1"},
                new FilterData { Filter1 = "test3", Filter2 = "Y", GoesToApp = "App3"},
                new FilterData { Filter1 = "test4", Filter2 = "Y", GoesToApp = "App3"},
                new FilterData { Filter1 = "test1", Filter2 = "Z", GoesToApp = "App1"},
            };
  

Теперь у меня есть тот Data , который также содержит вышеуказанные данные фильтров,

 var data = new Data
            {
                Id = 1,
                Filter2 = new List<string> { "X", "Y" },
                FilterValues = new List<FilterValue>
                {
                    new FilterValue {Filter1 = "test1", Value = "1"},
                    new FilterValue {Filter1 = "test2", Value = "2"},
                    new FilterValue {Filter1 = "test3", Value = "3"}
                }
            };
  

Здесь мне нужно выполнить фильтрацию Data с помощью основного списка (выше) Filter1 , Filter2 и мне нужно подготовить данные для каждого приложения (App1, App2 и так далее).

С помощью приведенного ниже кода я могу одновременно подготавливать данные только для одного приложения (пример, App1 ), и это дает мне желаемые данные, которые я хочу для этого приложения, на основе сравнения фильтров,

 var destData = new Data()
            {
                Id = 1,
                FilterValues = new List<FilterValue>()
            };

            var filter1DataForApp1 = filterData.Where(item =>
                    item.GoesToApp == "App1" amp;amp; data.Filter2.Contains(item.Filter2))
                .Select(item => item.Filter1);


            foreach (var f1 in filter1DataForApp1)
            {
                destData.FilterValues.AddRange(data.FilterValues.Where(a => a.Filter1 == f1));
            }
  

Для одного элемента в Data , если у меня 50 приложений, то приведенный выше код мне нужно запустить 50 раз для каждого приложения, чего я хочу избежать. Как это сделать? Возможно ли сгенерировать все данные приложений в одном запросе?

Здесь представлены разные структуры классов,

 public class FilterData
    {
        public string Filter1 { get; set; }
        public string Filter2 { get; set; }
        public string GoesToApp { get; set; }
    }

    public class Data
    {
        public int Id { get; set; }
        public List<string> Filter2 { get; set; }
        public List<FilterValue> FilterValues { get; set; }
    }

    public class FilterValue
    {
        public string Filter1 { get; set; }
        public string Value { get; set; }
    }
  

Ожидаемые выходные данные для,

App1 (только test1 и test2)

 var app1Data = new Data
        {
            Id = 1,
            Filter2 = null,
            FilterValues = new List<FilterValue>
            {
                new FilterValue {Filter1 = "test1", Value = "1"},
                new FilterValue {Filter1 = "test2", Value = "2"}
            }
        };
  

App2 (только test2)

 var app1Data = new Data
        {
            Id = 1,
            Filter2 = null,
            FilterValues = new List<FilterValue>
            {
                new FilterValue {Filter1 = "test2", Value = "2"}
            }
        };
  

и так далее…

Мне нужен один результат, что-то вроде List<GoesToApp, List<datafor that app>>

Комментарии:

1. Как это Data связано с GoesToApp ?

2. Можете ли вы показать, каков ваш ожидаемый результат… не совсем понятно. Id = 1 Ссылается на? App1 ИТАК, вы ищете destData коллекцию ссылок на ваши 3 приложения?

3. Спасибо @Jamiec, смотрите Мой ожидаемый результат для каждого приложения

4. У @Heretic Monkey Data есть несколько Filter1 , которые мне нужно разделить на распределенные вправо AppToGoes . Спасибо.

Ответ №1:

Я думаю, что вы ищете что-то вроде этого:

 var result = filterData.GroupBy(x => x.GoesToApp).ToDictionary(grp => grp.Key, grp => {        
        return new Data 
        {
            Id = 1,
            FilterValues = grp.Where(item => data.Filter2.Contains(item.Filter2)).SelectMany(item => data.FilterValues.Where(f => item.Filter1 == f.Filter1)).ToList() 
        };
    });
    
foreach(var item in result)
{
    Console.WriteLine(item.Key);
    foreach(var fv in item.Value.FilterValues)
        Console.WriteLine($"t{fv.Filter1}");
}
  

Живой пример: https://dotnetfiddle.net/xsomse

Комментарии:

1. Спасибо, но мне тоже нужна GoesToApp информация.

2. что-то вроде List<GoesToApp, List<datafor that app>>

3. @user584018 хорошо, см. Обновление — просто верните словарь с ключом в GesToApp качестве ключа. Это имеет то преимущество, что вы можете сделать result["App1"] , например

4. Супер сэр. Отлично… Не могли бы вы немного объяснить мне логику?

5. @user584018 логика точно такая же, как у вашего оригинала, просто сначала группировка по GoesToApp , чтобы вы могли вернуть их список