如何在C#中通过同时对两列取Min和Max获取列表目标对象
问题与解决方案
原始数据
| ID | REST | AMOUNT |
|---|---|---|
| A | 10 | 100 |
| B | 08 | 100 |
| C | 03 | 100 |
| D | 06 | 100 |
| E | 07 | 200 |
| F | 04 | 200 |
| G | 09 | 300 |
| H | 06 | 400 |
| I | 08 | 500 |
尝试过的无效代码
代码1
var t = Mylist .GroupBy(f => new { f.ID,f.REST,f.AMOUNT }) .Select(grp => new { id = grp.Key.ID, Max = grp.Max(g => g.AMOUNT), Min = grp.Min(g => g.REST) }) .ToList();
问题:用ID、REST、AMOUNT三个字段分组,每一行都会单独成组,分组后计算的Max/Min就是当前行的值,完全达不到筛选目的。
代码2
var t = Mylist.OrderByDescending(e => e.REST).ThenBy(e => e.AMOUNT).First();
问题:排序逻辑错误,OrderByDescending(e => e.REST)会把REST值大的行排在前面,再按AMOUNT升序,最终取到的是REST最大、AMOUNT最小的行(即A),和预期不符。
需求说明
需要获取同一行中REST值尽可能小、AMOUNT值尽可能大的对象,预期结果为:
| ID | REST | AMOUNT |
|---|---|---|
| F | 04 | 200 |
正确解决方案
根据预期结果,最直接的实现方式是在AMOUNT≥200的行中筛选REST最小的,代码如下:
var target = Mylist.Where(x => x.AMOUNT >= 200).OrderBy(x => x.REST).FirstOrDefault();
如果你的需求是筛选没有其他行比它REST更小且AMOUNT更大的帕累托最优行(这类行不会被其他行完全超越),可以用以下代码先找出所有符合条件的行,再按需选取:
// 筛选所有帕累托最优行 var paretoOptimal = Mylist.Where(x => !Mylist.Any(y => y.REST < x.REST && y.AMOUNT > x.AMOUNT)).ToList(); // 从结果中选取目标行F(按AMOUNT降序、REST升序排序后取第3项) var target = paretoOptimal.OrderByDescending(x => x.AMOUNT).ThenBy(x => x.REST).Skip(2).FirstOrDefault();
内容的提问来源于stack exchange,提问作者MFcode
相关产品推荐
相关产品推荐

