简体   繁体   English

LINQ Min()和Max()优化

[英]LINQ Min() and Max() optimisation

I'm having some trouble doing it right. 我在做正确的方面遇到了一些麻烦。

I need to pick the minimum and maximum for a list inside a list inside a list 我需要为列表中的列表中的列表选择最小值和最大值

Any thought how I can create a optimized type? 有没有想过如何创建优化类型?

var range = allFilteredCars
            .SelectMany(car => car.LeasingPlans
                .SelectMany(plan => plan.Durations)
                .Select(a => a.MonthlyPrice))
            .ToList();

        var min = range.Min();
        var max = range.Max();

The last Min() and Max() doesn't feel right. 最后一个Min()Max()感觉不对。

Any thoughts? 有什么想法吗?

I can think of only one way to calculate min and max just by iterating one time on the entire collection which can be done using foreach loop 我只想通过在整个集合上迭代一次来计算minmax一种方法,这可以使用foreach循环来完成

var min = Int32.MaxValue;
var max = Int32.MinValue;
foreach(var filteredCard in allFilteredCars)
{
    foreach(var leasingPlan in filteredCard.LeasingPlans) 
    {
        foreach(var car in leasingPlan.Durations) 
        {
          if(car.MonthlyPrice < min)
            min = car.MonthlyPrice;
          else if(car.MonthlyPrice > max)
            max = car.MonthlyPrice;
        }
     }
}

Assuming MonthlyPrice is of Int 假设MonthlyPriceInt

We will do a bad thing : a linq expression with a side effect. 我们会做一件坏事 :带有副作用的linq表达式。

int? min = null;
int? max = null;

allFilteredCars
    .SelectMany(car => car.LeasingPlans
        .SelectMany(plan => plan.Durations))
            .Select(a =>
            {
                if (min == null || a.MonthlyPrice < min.Value)
                {
                    min = a.MonthlyPrice;
                }

                if (max == null || a.MonthlyPrice > max.Value)
                {
                    max = a.MonthlyPrice;
                }

                return true;
            }).All(x => x);

In the end you don't really seem to need the range result... You only want the Min() and Max() , so we calculate it, and force the whole IEnumerable<> to be elaborated through the use of All() . 最后你似乎不需要range结果......你只需要Min()Max() ,所以我们计算它,并强制通过使用All()来详细阐述整个IEnumerable<> All()

You have to replace int? 你必须替换int? with the type of MonthlyPrice ! MonthlyPrice的类型!

I don't think you can get around the multiple SelectMany s but an Ordering in the query will get rid of the Min/Max. 我不认为你可以绕过多个SelectMany但查询中的Ordering将摆脱Min / Max。 This should be quicker as you are then only sorting once: 这应该更快,因为你只排序一次:

var range = allFilteredCars
        .SelectMany(car => car.LeasingPlans
            .SelectMany(plan => plan.Durations)
            .Select(a => a.MonthlyPrice))
            .OrderBy(a => a))
        .ToList();

    var min = range[0]; // get the first
    var max = range[range.Count-1];  // get the last

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM