如何让LINQ返回集合中具有最大值的对象的索引?

我有一个不可变对象列表(在我的特定情况下是一个Tuple列表Tuple ),我想更改具有最高Item2值的那个。

理想情况下,我可以使用一个IndexOfMaxBy函数,所以我可以这样做:

 var indexOfPointWithHighestItem2 = myList.IndexOfMaxBy(x => x.Item2); var original = myList[indexOfPointWithHighestItem2]; myList[indexOfPointWithHighestItem2] = new Tuple(original.Item1, original.Item2 - 1); 

我已经看到如何让LINQ返回具有给定属性的最大值的对象? ,并使用Jon Skeet的MaxByfunction与Select我可以做到:

 var indexOfPointWithHighestItem2 = myList.Select((x, i) => new { Index = i, Value = x }) .MaxBy(x => x.Item2).Index; 

但是这会为我列表中的每个对象创建一个新对象,并且必须有一个更简洁的方法。 有没有人有任何好的建议?

好吧,如果你想,你当然可以自己写一个IndexOfMaxBy扩展。

实施例(未测试):

 public static int IndexOfMaxBy (this IEnumerable source, Func selector, IComparer comparer = null ) { //null-checks here using (var erator = source.GetEnumerator()) { if (!erator.MoveNext()) throw new InvalidOperationException("Sequence is empty."); if (comparer == null) comparer = Comparer.Default; int index = 0, maxIndex = 0; var maxProjection = selector(erator.Current); while (erator.MoveNext()) { index++; var projectedItem = selector(erator.Current); if (comparer.Compare(projectedItem, maxProjection) > 0) { maxIndex = index; maxProjection = projectedItem; } } return maxIndex; } } 

用法:

 var indexOfPointWithHighestItem2 = myList.IndexOfMaxBy(x => x.Item2); 

看起来在List上定义了一个FindIndex方法,它非常适用于此:

 double max = myList.Max(t => t.Item2); int index = myList.FindIndex(t => t.Item2 == max);