在C#中如何先分组再对组内元素进行排序?
按属性分组并组内排序的LINQ实现问题
假设有一个包含int类型Val1和double类型Val2属性的对象列表,需要按Val1对列表分组,同时每个分组内按Val2进行升序排序。
示例输入输出
输入列表
Val1 Val2 1 2.4 2 1.3 1 1.9 2 5.1
期望输出
Val1 Val2 1 1.9 1 2.4 2 1.3 2 5.1
错误的尝试方案
方案一:先分组再全局排序
list = list.GroupBy(x => x.Val1).SelectMany(x => x).OrderBy(x => x.Val2).ToList();
这段代码先按Val1分组并展开,最后全局按Val2排序,完全破坏了分组结构,所有元素只按Val2排序,不符合需求。
方案二:先全局排序再分组
list = list.OrderBy(x => x.Val2).GroupBy(x => x.Val1).SelectMany(x => x).ToList();
这段代码先按Val2全局排序,再按Val1分组展开,虽然每组内的Val2是有序的,但分组的Val1顺序无法保证(示例中出现了从高到低的情况),直接反转列表会打乱组内的Val2排序,同样不满足要求。
正确的实现方式
方式一:分组后组内排序+分组按键排序
先按Val1分组,对每个分组内的元素按Val2排序,同时保证分组按Val1升序排列:
list = list.GroupBy(x => x.Val1) .OrderBy(group => group.Key) // 按分组键Val1升序排列所有分组 .SelectMany(group => group.OrderBy(item => item.Val2)) // 每个分组内按Val2升序排序后展开 .ToList();
方式二:多条件全局排序(更简洁)
直接通过两次排序实现:先按Val1排序,让相同Val1的元素聚集,再对同一Val1内的元素按Val2排序,效果等价于分组后组内排序:
list = list.OrderBy(x => x.Val1).ThenBy(x => x.Val2).ToList();
这种写法更简洁高效,完全满足需求。
内容的提问来源于stack exchange,提问作者user20477354
相关产品推荐
相关产品推荐

