如何用C# LINQ筛选含最高IsFavourite=true的RealValue的ValueGroup
用LINQ筛选符合条件的ValueGroup
定义的C#类
public class ValueGroup { public string Name { get; set; } public List<Value> Values { get; set; } } public class Value { public int RealValue { get; set; } public bool IsFavourite { get; set; } }
(注:原代码中Value类的IsFavourite属性缺少闭合的},已修正)
创建的ValueGroup列表
var valueList = new List<ValueGroup> { new ValueGroup { Name = "1st Group", Values = new List<Value> { new Value { RealValue = 6, IsFavourite = false }, new Value { RealValue = 2, IsFavourite = true }, new Value { RealValue = 4, IsFavourite = false } } }, new ValueGroup { Name = "2nd Group", Values = new List<Value> { new Value { RealValue = 7, IsFavourite = false }, new Value { RealValue = 3, IsFavourite = true }, new Value { RealValue = 8, IsFavourite = true } } }, new ValueGroup { Name = "3rd Group", Values = new List<Value> { new Value { RealValue = 9, IsFavourite = false }, new Value { RealValue = 1, IsFavourite = true }, new Value { RealValue = 5, IsFavourite = false } } } };
需求
需要筛选出这样的ValueGroup:其嵌套的Values列表中,IsFavourite为true的元素里RealValue的值最大。示例中应选中第2组(第3组有更大的RealValue,但该元素IsFavourite为false)。请问能否用LINQ实现该需求?
实现方案
当然可以用LINQ实现,以下是两种实用写法:
写法一:分步计算
先过滤掉无收藏元素的组,再找出最大的收藏值,最后匹配对应组:
// 过滤出包含收藏元素的组 var validGroups = valueList.Where(g => g.Values.Any(v => v.IsFavourite)); if (!validGroups.Any()) { // 处理无符合条件组的情况,比如返回null或抛出提示 return null; } // 计算所有有效组中,收藏元素的最大RealValue int maxFavRealValue = validGroups.Max(g => g.Values.Where(v => v.IsFavourite).Max(v => v.RealValue)); // 筛选出符合条件的组 var targetGroup = validGroups.FirstOrDefault(g => g.Values.Where(v => v.IsFavourite).Max(v => v.RealValue) == maxFavRealValue);
写法二:链式简化
通过排序直接取首位,代码更简洁:
var targetGroup = valueList .Where(g => g.Values.Any(v => v.IsFavourite)) // 排除无收藏元素的组 .OrderByDescending(g => g.Values.Where(v => v.IsFavourite).Max(v => v.RealValue)) .FirstOrDefault();
说明
- 两种写法都会选中示例中的第2组,因为它的收藏元素最大RealValue为8,是所有组中最高的。
- 代码中加入了对无收藏元素组的过滤,避免出现
InvalidOperationException(当组内没有IsFavourite为true的元素时,Max方法会报错)。 - 如果存在多个组的收藏元素最大RealValue相同,
FirstOrDefault会返回第一个匹配的组;若要获取所有匹配组,只需将FirstOrDefault替换为Where即可。
内容的提问来源于stack exchange,提问作者chevez
相关产品推荐
相关产品推荐

