如何使用LINQ获取数组中最高值的索引?
我有一个双打数组,我想要最高值的索引。 这些是我到目前为止提出的解决方案,但我认为必须有一个更优雅的解决方案。 想法?
double[] score = new double[] { 12.2, 13.3, 5, 17.2, 2.2, 4.5 }; int topScoreIndex = score.Select((item, indx) => new {Item = item, Index = indx}).OrderByDescending(x => x.Item).Select(x => x.Index).First(); topScoreIndex = score.Select((item, indx) => new {Item = item, Index = indx}).OrderBy(x => x.Item).Select(x => x.Index).Last(); double maxVal = score.Max(); topScoreIndex = score.Select((item, indx) => new {Item = item, Index = indx}).Where(x => x.Item == maxVal).Select(x => x.Index).Single();
我建议编写自己的扩展方法(编辑为通用IComparable
约束。)
public static int MaxIndex(this IEnumerable sequence) where T : IComparable { int maxIndex = -1; T maxValue = default(T); // Immediately overwritten anyway int index = 0; foreach (T value in sequence) { if (value.CompareTo(maxValue) > 0 || maxIndex == -1) { maxIndex = index; maxValue = value; } index++; } return maxIndex; }
请注意,如果序列为空,则返回-1。
关于特点的一句话:
至于这个“是否是LINQ”:如果它被列为标准LINQ查询运算符之一,你会把它算作LINQ吗? 它感觉特别陌生或与其他LINQ运营商不同吗? 如果MS将它作为新运算符包含在.NET 4.0中,它会是LINQ吗?
编辑:如果你真的,真的非常渴望使用LINQ(而不仅仅是获得一个优雅的解决方案),那么这里仍然是O(n)并且只评估序列一次:
int maxIndex = -1; int index=0; double maxValue = 0; int urgh = sequence.Select(value => { if (maxIndex == -1 || value > maxValue) { maxIndex = index; maxValue = value; } index++; return maxIndex; }).Last();
它很可怕,我建议你根本不使用它 – 但它会起作用。
嗯,为什么要让它过于复杂? 这是最简单的方法。
var indexAtMax = scores.ToList().IndexOf(scores.Max());
是的,您可以使用扩展方法来使用更少的内存,但除非您处理大型数组,否则您将永远不会注意到差异。
var scoreList = score.ToList(); int topIndex = ( from x in score orderby x select scoreList.IndexOf(x) ).Last();
如果score
不是数组,这不会是一半坏…
MoreLinq是一个提供此function的库。
我今天遇到了这个问题(要获得年龄最大的用户数组中的索引),我这样做了:
var position = users.TakeWhile(u => u.Age != users.Max(x=>x.Age)).Count();
这是在C#类,所以它的noob解决方案,我相信你的更好:)
这不是唯一基于聚合的解决方案,但这实际上只是一个单线解决方案。
double[] score = new double[] { 12.2, 13.3, 5, 17.2, 2.2, 4.5 }; var max = score.Select((val,ix)=>new{val,ix}).Aggregate(new{val=-1.0,ix=-1},(z,last)=>z.val>last.val?z:last); Console.WriteLine ("maximum value is {0}", max.val ); Console.WriteLine ("index of maximum value is {0}", max.ix );
最糟糕的复杂性是O(2N)〜= O(N),但它需要枚举该集合两次。
void Main() { IEnumerable numbers = new int[] { 1, 2, 3, 4, 5 }; int max = numbers.Max (); int index = -1; numbers.Any (number => { index++; return number == max; }); if(index != 4) { throw new Exception("The result should have been 4, but " + index + " was found."); } "Simple test successful.".Dump(); }
如果你想看看LINQy的东西,因为它纯粹是function性的,那么Jon Skeets上面的回答可以改写为:
public static int MaxIndex(this IEnumerable sequence) where T : IComparable { return sequence.Aggregate( new { maxIndex = -1, maxValue = default(T), thisIndex = 0 }, ((agg, value) => (value.CompareTo(agg.maxValue) > 0 || agg.maxIndex == -1) ? new {maxIndex = agg.thisIndex, maxValue = value, thisIndex = agg.thisIndex + 1} : new {maxIndex = agg.maxIndex, maxValue = agg.maxValue, thisIndex = agg.thisIndex + 1 })). maxIndex; }
这与其他答案具有相同的计算复杂度,但是对于内存更加挥霍,为可枚举的每个元素创建中间答案。
上述就是C#学习教程:如何使用LINQ获取数组中最高值的索引?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1004616.html