Использование linq для возврата списка объектов, где сумма атрибута является Max () в списке списка - PullRequest
2 голосов
/ 02 октября 2019

У меня есть список списков объектов (List<List<Product>>). Я хочу вернуть только один список из списка, где sum из cost во внутреннем списке является самым высоким.

Я пытаюсь использовать запрос linq в C # для достижения этой цели. Хотя я не слишком знаком с этими запросами linq.

List<List<Product>> query = (from lists in ListOfList
                            where lists.Sum(x => x.factor) <= 10
                            orderby lists.Sum(x => x.cost) descending
                            select lists).ToList();

List<Product> tempList = query.FirstOrDefault();

Я хочу вернуть один список из доступных списков, где условия выполняются. Прикрепленный код возвращает нули.

Спасибо

Ответы [ 3 ]

0 голосов
/ 02 октября 2019

попробуйте это:

List<Product> list1 = new List<Product>() { new Product(1), new Product(3), new Product(2), new Product(6), new Product(5)};
        List<Product> list2 = new List<Product>() { new Product(14), new Product(10), new Product(8), new Product(6), new Product(1) };
        List<Product> list3 = new List<Product>() { new Product(11), new Product(22), new Product(38), new Product(14), new Product(155) }; 
        List<List<Product>> products = new List<List<Product>>() { list1, list2, list3 }; //just some dummy data

        var highestSumOfPrices = products.Max(lp => lp.Sum(p => p.Cost));

        var result = products
            .FirstOrDefault(lp => lp.Sum(p => p.Cost) == highestSumOfPrices);

, что мы делаем здесь: сначала мы берем наибольшую сумму всех цен в списке списков. затем мы берем первый список, который соответствует условию: сумма стоимости продуктов списка равна наибольшему из всех списков в коллекции. Я надеюсь, что это работает для вас. в качестве альтернативы вы можете попробовать:

var result = products.OrderByDescending(pl=>pl.Sum(p=>p.Cost)).First();

вы можете упорядочить (в порядке убывания) список списков по сумме затрат на их продукцию и просто взять первый результат;это более простое решение, работает так же хорошо, но я ничего не могу сказать о производительности

0 голосов
/ 02 октября 2019

Я написал этот тестовый код вместе с вашим запросом, и он работает.

static void Test()
{
  // Test data
  var ListOfList = new List<List<Product>>();
  var list1 = new List<Product>();
  list1.Add(new Product { name = "item 1", factor = 1, cost = 10 });
  list1.Add(new Product { name = "item 2", factor = 5, cost = 20 });
  var list2 = new List<Product>();
  list2.Add(new Product { name = "item 3", factor = 30, cost = 50 });
  list2.Add(new Product { name = "item 4", factor = 4, cost = 40 });
  var list3 = new List<Product>();
  list3.Add(new Product { name = "item 5", factor = 2, cost = 100 });
  list3.Add(new Product { name = "item 6", factor = 3, cost = 150 });
  var list4 = new List<Product>();
  list4.Add(new Product { name = "item 5", factor = 2, cost = 60 });
  list4.Add(new Product { name = "item 6", factor = 3, cost = 5 });
  ListOfList.Add(list1);
  ListOfList.Add(list2);
  ListOfList.Add(list3);
  ListOfList.Add(list4);
  // Query
  var query = ( from list in ListOfList
                where list.Sum(x => x.factor) <= 10
                orderby list.Sum(x => x.cost) descending
                select list ).FirstOrDefault();
  // Display results
  if ( query != null )
    foreach ( var item in query )
      Console.WriteLine($"{item.name} cost {item.cost} with factor {item.factor}");
}

class Product
{
  public string name;
  public int factor;
  public int cost;
}

Результаты

item 5 cost 100 with factor 2
item 6 cost 150 with factor 3
0 голосов
/ 02 октября 2019

Если я вас правильно понял, вы ищете ArgMax ( Аргумент такой, чтобы коллекция достигла значения Максимальное ), стандартный Linq не предоставляет такой метод, но его можно эмулировать с помощью Aggregate:

List<List<Product>> data = ...

List<Product> result = data
  .Select(list => new {
     list,                                    // list
     max = list
       .Where(product => product.Factor < 10) 
       .Sum(product => product.cost)          // with criterium to maximize
   })
  .Aggregate((s, a) => s.max > a.max ? s : a) // ArgMax implementation
  .list;                                      // We want list only (without max) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...