【发布时间】:2018-03-14 10:18:14
【问题描述】:
我写了一个小测试用例来解释我的问题。
我能够以某种方式查询我的数据库以获取元组列表。
我想从中提取一个元组列表,没有重复,按 Item1 排序...这很好,但现在我总是想在 Item2 未按降序排序时删除元组。
我可以通过创建一个临时列表然后删除坏元组来做到这一点。
您能帮我直接在 linq 中执行此操作吗(如果可能的话?)?
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace Web.Test
{
[TestFixture]
public class ListListTupleTest
{
[TestCase]
public void TestCaseTest_1()
{
var input = new List<List<Tuple<int, decimal>>>
{
new List<Tuple<int, decimal>>
{
new Tuple<int, decimal>(5, 20),
new Tuple<int, decimal>(8, 10)
},
new List<Tuple<int, decimal>>
{
new Tuple<int, decimal>(7, 17),
new Tuple<int, decimal>(12, 9)
},
new List<Tuple<int, decimal>>
{
new Tuple<int, decimal>(7, 17),
new Tuple<int, decimal>(15, 10)
}
};
var goal = new List<Tuple<int, decimal>>()
{
new Tuple<int, decimal>(5, 20),
new Tuple<int, decimal>(7, 17),
new Tuple<int, decimal>(8, 10),
new Tuple<int, decimal>(12, 9)
};
var result = myFunction(input);
CollectionAssert.AreEqual(result, goal);
}
private List<Tuple<int, decimal>> myFunction(List<List<Tuple<int, decimal>>> myList)
{
var tmp = myList
.SelectMany(x => x.ToArray())
.Distinct()
.OrderBy(x => x.Item1)
.ToList();
var result = new List<Tuple<int, decimal>>();
if (tmp.Any())
{
result.Add(tmp.First());
decimal current = tmp.First().Item2;
foreach (var tuple in tmp.Skip(1))
{
if (tuple.Item2 < current)
{
result.Add(tuple);
current = tuple.Item2;
}
}
}
return result;
}
}
}
【问题讨论】:
-
如果您需要访问上一个或下一个项目,经典循环通常是更好的方法。 LINQ 方法通常不太可读且效率较低。但是,问题更适合:codereview.stackexchange.com
-
我同意蒂姆的观点。当您需要比较列表中的项目时,Linq 会变得混乱。最好使用经典循环编写代码。我经常创建一个帮助方法来进行比较,然后将帮助器添加到 linq 中。
-
问题不仅在于您必须访问上一项,而且您必须保留最后一个最高的项,如果多个项无效,则不一定是上一项。订单可能是
10,15,11,那么不应添加最后的 11,因为它仍然高于最后一个有效的 10。循环非常适合此用例。 -
没错,我的问题是你想如何处理
10,15,11?15和11都被拒绝了吗?