我有一个列表List<int> myList = new List<int>() { 10, 20, 8, 20, 9, 5, 20, 10 };
,我想选择第二个最高值,在本例中为10
。我编写了这段代码,它可以正常工作,但是我想知道是否有更短,更好的东西。
List<int> myList = new List<int>() { 10, 20, 8, 20, 9, 5, 20, 10 };
myList = myList.Distinct().ToList();
var descendingOrder = myList.OrderByDescending(i => i);
var sec = descendingOrder.Skip(1).First();
答案 0 :(得分:9)
您可以停止使用中间变量和ToList()
var secondHighest =
myList
.Distinct()
.OrderByDescending(i => i);
.Skip(1)
.First();
这将与您的版本相同,但只需要一个语句,而不是三个。
我发现阅读代码清单要容易得多。
每个LINQ方法都在其自己的行上调用,并且没有中间变量,尤其是那些发生变化的中间变量(重新分配了myList
,这使得它很难理解)。
答案 1 :(得分:7)
Dave's建议在一个管道中执行所有操作确实很好,因为它避免了:
另一方面,就效率而言,最好对源列表执行两次传递,而不是仅对第二个列表进行“排序”,而不是对整个列表进行“排序”。
var maximum = myList.Max();
var secondMaximum = myList.Where(x => x < maximum).Max();
答案 2 :(得分:0)
我认为我会避免使用LINQ,而只是使用一个标准的“循环遍历每个元素,如果电流高于最大值,则将current max推到第二位,将current value推到current max”
int sec = int.MinValue;
for(int i =0, m= int.MinValue; i <list.Length; i++)
if(list[i] > m){
sec = m;
m = list[i];
}
您给定的逻辑将这些值区分开,因此即使存在三个值为20的列表,看起来20也并不是列表中第二高的值。这可以通过>实现。如果我使用了> =,则每20个都会滚动变量,并且其行为就像无差别
如果您对性能感兴趣,请在一个包含几百万个条目的列表上进行测试,然后选择满足您对可读性与速度的需求的一个
答案 3 :(得分:0)
它不是LINQ-y,但它是O(N)并且易于阅读:
public static int TheSecondMax()
{
List<int> myList = new List<int>() { 10, 20, 8, 20, 9, 5, 20, 10 };
int max = int.MinValue;
int secondMax = int.MinValue;
foreach (var item in myList)
{
if (item > max)
{
max = item;
}
if (item > secondMax && item < max)
{
secondMax = item;
}
}
return secondMax;
}