Получить пересечение двух списков с определенными критериями

#c# #linq

#c# #linq ( ссылка ) #linq

Вопрос:

Допустим, у меня есть два списка автомобилей

Список 1:

  • «Ferrari», 2005, «350 000 долларов»
  • «BMW», 2009, «29 000 долларов»
  • «Audi», 2011, «33 000 долларов»

Список 2:

  • «Бесконечность»,2005, «267 000 долларов»
  • «BMW», 2009, «45 000 долларов»
  • «Ferrari», 2005, «330 000 долларов»
  • «Toyota», 2009, «35 000 долларов»

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

  • «Ferrari», 2005, «330 000 долларов»
  • «BMW», 2009, «29 000 долларов»

потому что это автомобили, которые повторяются с именем, и у них наименьшая цена

Ответ №1:

Полностью непроверенный, но как насчет чего-то подобного?

 var result = from c1 in List1
             join c2 in List2 on c1.Name equals c2.Name
             select new CarInfo()
             {
                 Name = c1.Name, // Doesn't really matter which you take
                 Year = c1.Price < c2.Price ? c1.Year : c2.Year,
                 Price = c1.Price < c2.Price ? c1.Price : c2.Price
             };
  

Ответ №2:

Что-то вроде этого? Я предполагаю, что у вас есть бит IEquality CarComparer для пересечения.

 var cheapCars = list1.Intersect(list2, new CarComparer()).
    OrderBy(c => c.Price).
        GroupBy(c => c.Name).
            Select(g => g.FirstOrDefault());
  

Возможно, вам придется исправить синтаксис…

Ответ №3:

Следующий запрос будет сопоставлять автомобили по Brand и Year свойствам. Если вас интересует только Brand , вы можете изменить критерии объединения, чтобы соответствовать этой цели.

 var results = from car1 in list1
              join car2 in list2 
                on new { car1.Brand, car1.Year } 
                equals new { car2.Brand, car2.Year }
              select (car1.Price <= car2.Price) ? car1 : car2;