如何使用 LINQ 获取子列表中具有最高值 属性 的实例?

How can I use LINQ to get the instance with the highest value of a property in a child list?

我有以下 class 结构:

public class FirstClass
{
    public string EmployeeNo { get; set; }

    public List<SecondClass> SecondClass { get; set; }
}

public class SecondClass
{
    public int Count { get; set; }
}

我正在使用此代码:

var result = FirstClass.Where(fc => fc.SecondClass.Aggregate((item1, item2) => item1.Count > item2.Count ? item1 : item2));

但是,它会导致此编译器错误:

Cannot implicitly convert type of "SecondClass" into bool

如何获取包含SecondClass对象的SecondClass.Count属性对象的最高值?如果多个 FirstClass 对象具有相同的最高值,它应该 return 第一个这样的对象。

您可以select 计算SecondClass 中每个项目的数量并使用Max 求出最大值。然后你 select FirstClass 中每个项目的这个值并再次使用 Max:

int highestCount = input.Select(x => x.SecondClass.Select(y => y.Count).Max()).Max();

如果要查找计数最高的项目,可以将第一个 Select 替换为 OrderByDescending,将第二个 Max 替换为 FirstOrDefault:

var itemWithHighestCount = input.OrderByDescending(x => x.SecondClass.Select(y => y.Count).Max()).FirstOrDefault();

在线演示:https://dotnetfiddle.net/0rWARC

获取给定 FirstClass 实例的 SecondClass.Count 的最大值很简单...

int maxSecondClassCount = first.SecondClass.Max(second => second.Count);

...虽然请注意,如果 first.SecondClass 为空,Max()throwInvalidOperationException。然后您可以使用...

  • ....NET 6MaxBy() method 获取具有最大 SecondClass.Count 值的 FirstClass 实例...
    FirstClass firstClassWithMaxSecondClassCount = firstClassCollection.MaxBy(first => first.SecondClass.Max(second => second.Count));
    
    MoreLINQ library also provides a MaxBy extension method.
  • ...所有 .NET (Framework/Core) 版本的 Aggregate() method 支持 LINQ 枚举您的 FirstClass 实例,保持跟踪具有 SecondClass.Count 最大值的实例和 return 最后的 FirstClass 实例...
    FirstClass firstClassWithMaxSecondClassCount = firstClassCollection.Aggregate(
        (element: default(FirstClass), count: 0), // The initial value of currentMax
        (currentMax, currentElement) => {
            int currentElementMaxCount = currentElement.SecondClass.Max(second => second.Count);
    
            return currentElementMaxCount > currentMax.count
                ? (element: currentElement, count: currentElementMaxCount)
                : currentMax;
        },
        currentMax => currentMax.element          // The return value given the final value of currentMax
    );
    
    它使用 tupleSecondClass.Count 的最大值与包含的 FirstClass 实例一起存储,这样就不必在每次调用时重新计算该值。否则,可以使用这种不那么复杂但性能也较差的代码......
    FirstClass firstClassWithMaxSecondClassCount = firstClassCollection.Aggregate(
        (maxElement, currentElement) => 
            currentElement.SecondClass.Max(second => second.Count) > maxElement.SecondClass.Max(second => second.Count)
                ? currentElement : maxElement
    );
    
    使用 Aggregate() 而不是排序并取结果一端的元素的优点是 Aggregate() 只需要存储另一个值——累加器 (currentMax/maxElement 以上)——因为它枚举了源序列,而排序将需要将整个序列缓冲到那个点。