如何使用 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();
获取给定 FirstClass
实例的 SecondClass.Count
的最大值很简单...
int maxSecondClassCount = first.SecondClass.Max(second => second.Count);
...虽然请注意,如果 first.SecondClass
为空,Max()
将 throw
和 InvalidOperationException
。然后您可以使用...
- ....NET 6 的
MaxBy()
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
);
它使用 tuple 将 SecondClass.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
以上)——因为它枚举了源序列,而排序将需要将整个序列缓冲到那个点。
我有以下 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();
获取给定 FirstClass
实例的 SecondClass.Count
的最大值很简单...
int maxSecondClassCount = first.SecondClass.Max(second => second.Count);
...虽然请注意,如果 first.SecondClass
为空,Max()
将 throw
和 InvalidOperationException
。然后您可以使用...
- ....NET 6 的
MaxBy()
method 获取具有最大SecondClass.Count
值的FirstClass
实例...
MoreLINQ library also provides aFirstClass firstClassWithMaxSecondClassCount = firstClassCollection.MaxBy(first => first.SecondClass.Max(second => second.Count));
MaxBy
extension method. - ...所有 .NET (Framework/Core) 版本的
Aggregate()
method 支持 LINQ 枚举您的FirstClass
实例,保持跟踪具有SecondClass.Count
最大值的实例和 return 最后的FirstClass
实例...
它使用 tuple 将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 );
SecondClass.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
以上)——因为它枚举了源序列,而排序将需要将整个序列缓冲到那个点。