/// <summary> /// Функция окончательной обработки результатов запросов к провайдерам /// </summary> /// <param name="result"></param> /// <param name="toursOrder"></param> /// <returns></returns> private List <Tour> HandleResults(List <Tour> result, ToursOrderEnum toursOrder) { ConcurrentBag <Tour> tours = new ConcurrentBag <Tour>(); // группируем результат по полям и сортируем туры в группе var groups = result.AsParallel().GroupBy(tour => new { tour.HotelName, tour.DepartureCityName, tour.DepartureDate, tour.ArrivalDate, tour.HotelCheckInDate, tour.HotelNightCount, tour.RoomTypeName }, (key, values) => values.OrderBy(v => v.HotelNightPriceByPerson)).ToArray(); Parallel.ForEach(groups, group => { if (group.Count() > 1) { //Tour preferredTour; Tour minPriceTour = group.First(); //берем минимальный тур по цене //!!! тут не понятна в ТЗ суть обработки получается что берем всегда предпочитаемый, // если он между мин и макс ценой, тк сказанно что разница со всеми не более x %, // может быть разница между ним и всеми, которые дешевле его if (minPriceTour.ProviderName.ToLower() == _options.Value.PreferredProvider.ToLower())// если минимальный по цене тур от предпочитаемого провайдера то { tours.Add(minPriceTour); } else { //поскольку в ТЗ непонятно как сравнивать будем со следующим который дешевле, тк с другими смысла нет var preferredTour = group //найдем предпочитаемый тур и возмем его индекс .AsParallel() .Where(tour => tour.ProviderName.ToLower() == _options.Value.PreferredProvider.ToLower()) .Select((tour, index) => new { index, tour }).FirstOrDefault(); if (preferredTour.index == 1 && //значит предпочитаемый тур следующий за минимальным тк список отсортирован, сравним цену ((preferredTour.tour.HotelNightPriceByPerson - minPriceTour.HotelNightPriceByPerson) / minPriceTour.HotelNightPriceByPerson) * 100 <= _options.Value.DifferenceBetweenProviderPrice) { tours.Add(preferredTour.tour); } else { var cheaperTour = group.ElementAtOrDefault(preferredTour.index - 1); if (((preferredTour.tour.HotelNightPriceByPerson - cheaperTour.HotelNightPriceByPerson) / cheaperTour.HotelNightPriceByPerson) * 100 <= _options.Value.DifferenceBetweenProviderPrice) { tours.Add(preferredTour.tour); } else { tours.Add(minPriceTour); } } } } else { tours.Add(group.First()); } }); //сортируем список (по умолчанию по цене) return(tours.OrderBy(tour => tour, new TourComparer(toursOrder)).ToList()); }
public TourComparer(ToursOrderEnum toursOrder) { _toursOrder = toursOrder; }