给出这样一个列表:
List<int> intList = new List<int>(); intList.Add(5); intList.Add(10); intList.Add(15); intList.Add(46);
List<int> intList = new List<int>();
intList.Add(5);
intList.Add(10);
intList.Add(15);
intList.Add(46);
如何获得列表中最大元素的索引?在这种情况下,它的索引为3。编辑:标准LINQ没有提供这些功能,这是一个遗憾。
kcwpcxri1#
这样:
var maxIndex = foo.IndexOf(foo.Max());
wydwbb8l2#
下面是一个简单 * 且相对有效**的解决方案:
int indexMax = !intList.Any() ? -1 : intList .Select( (value, index) => new { Value = value, Index = index } ) .Aggregate( (a, b) => (a.Value > b.Value) ? a : b ) .Index;
int indexMax
= !intList.Any() ? -1 :
intList
.Select( (value, index) => new { Value = value, Index = index } )
.Aggregate( (a, b) => (a.Value > b.Value) ? a : b )
.Index;
1.如果列表为空,!intList.Any() ? -1 :将强制执行-1;
!intList.Any() ? -1 :
-1
Select
int
Value
Index
Aggregate
toiithl63#
这里有一个自定义的LINQ方法,我相信它可以满足您的需求。(我以前有另一个做投影的,但你可以只调用Select来做,因为你只需要索引。
public static int MaxIndex<T>(this IEnumerable<T> source){ IComparer<T> comparer = Comparer<T>.Default; using (var iterator = source.GetEnumerator()) { if (!iterator.MoveNext()) { throw new InvalidOperationException("Empty sequence"); } int maxIndex = 0; T maxElement = iterator.Current; int index = 0; while (iterator.MoveNext()) { index++; T element = iterator.Current; if (comparer.Compare(element, maxElement) > 0) { maxElement = element; maxIndex = index; } } return maxIndex; }}
public static int MaxIndex<T>(this IEnumerable<T> source)
{
IComparer<T> comparer = Comparer<T>.Default;
using (var iterator = source.GetEnumerator())
if (!iterator.MoveNext())
throw new InvalidOperationException("Empty sequence");
}
int maxIndex = 0;
T maxElement = iterator.Current;
int index = 0;
while (iterator.MoveNext())
index++;
T element = iterator.Current;
if (comparer.Compare(element, maxElement) > 0)
maxElement = element;
maxIndex = index;
return maxIndex;
63lcw9qa4#
下面是如何使用LINQ在一个(长)行中完成此操作,只需一次遍历集合。它应该适用于任何IEnumerable<int>,而不仅仅是列表。
IEnumerable<int>
int maxIndex = intList .Select((x, i) => new { Value = x, Index = i }) .Aggregate ( new { Value = int.MinValue, Index = -1 }, (a, x) => (a.Index < 0) || (x.Value > a.Value) ? x : a, a => a.Index );
int maxIndex = intList
.Select((x, i) => new { Value = x, Index = i })
.Aggregate
(
new { Value = int.MinValue, Index = -1 },
(a, x) => (a.Index < 0) || (x.Value > a.Value) ? x : a,
a => a.Index
);
下面是上面的非LINQ等价物,使用foreach循环。(同样,只需一次遍历集合,并且应该适用于任何IEnumerable<int>。
foreach
int maxIndex = -1, maxValue = int.MinValue, i = 0;foreach (int v in intList){ if ((maxIndex < 0) || (v > maxValue)) { maxValue = v; maxIndex = i; } i++;}
int maxIndex = -1, maxValue = int.MinValue, i = 0;
foreach (int v in intList)
if ((maxIndex < 0) || (v > maxValue))
maxValue = v;
maxIndex = i;
i++;
如果你知道集合是一个IList<int>,那么简单的for循环可能是最简单的解决方案:
IList<int>
for
int maxIndex = -1, maxValue = int.MinValue;for (int i = 0; i < intList.Count; i++){ if ((maxIndex < 0) || (intList[i] > maxValue)) { maxValue = intList[i]; maxIndex = i; }}
int maxIndex = -1, maxValue = int.MinValue;
for (int i = 0; i < intList.Count; i++)
if ((maxIndex < 0) || (intList[i] > maxValue))
maxValue = intList[i];
7kqas0il5#
我无法改进Jon Skeet对一般情况的回答,所以我将在int列表的特定情况下获得“高性能”奖。
public static class Extensions{ public static int IndexOfMaximumElement(this IList<int> list) { int size = list.Count; if (size < 2) return size - 1; int maxValue = list[0]; int maxIndex = 0; for (int i = 1; i < size; ++i) { int thisValue = list[i]; if (thisValue > maxValue) { maxValue = thisValue; maxIndex = i; } } return maxIndex; }
public static class Extensions
public static int IndexOfMaximumElement(this IList<int> list)
int size = list.Count;
if (size < 2)
return size - 1;
int maxValue = list[0];
for (int i = 1; i < size; ++i)
int thisValue = list[i];
if (thisValue > maxValue)
maxValue = thisValue;
gopyfrb36#
以下是我的解决方案:
public static int IndexOfMax(this IList<int> source){ if (source == null) throw new ArgumentNullException("source"); if (source.Count == 0) throw new InvalidOperationException("List contains no elements"); int maxValue = source[0]; int maxIndex = 0; for (int i = 1; i < source.Count; i++) { int value = source[i]; if (value > maxValue) { maxValue = value; maxIndex = i; } } return maxIndex;}
public static int IndexOfMax(this IList<int> source)
if (source == null)
throw new ArgumentNullException("source");
if (source.Count == 0)
throw new InvalidOperationException("List contains no elements");
int maxValue = source[0];
for (int i = 1; i < source.Count; i++)
int value = source[i];
if (value > maxValue)
maxValue = value;
pvabu6sv7#
如果你喜欢,这里是非linq方法:
private int ReturnMaxIdx(List<int> intList) { int MaxIDX = -1; int Max = -1; for (int i = 0; i < intList.Count; i++) { if (i == 0) { Max = intList[0]; MaxIDX = 0; } else { if (intList[i] > Max) { Max = intList[i]; MaxIDX = i; } } } return MaxIDX; }
private int ReturnMaxIdx(List<int> intList)
int MaxIDX = -1;
int Max = -1;
if (i == 0)
Max = intList[0];
MaxIDX = 0;
else
if (intList[i] > Max)
Max = intList[i];
MaxIDX = i;
return MaxIDX;
这至少是一次遍历列表。希望这能帮上忙凯尔
mfuanj7w8#
使用自定义函数,使用Max()和IndexOf()会花费更多。
q35jwt9p9#
简化.
int MaxIndex = list.DefaultIfEmpty().Select((v, i) => new { v, i }).Aggregate((a, b) => (a.v > b.v) ? a : b).i;
9条答案
按热度按时间kcwpcxri1#
这样:
wydwbb8l2#
下面是一个简单 * 且相对有效**的解决方案:
1.如果列表为空,
!intList.Any() ? -1 :
将强制执行-1
;Select
将把每个int
元素投影到一个匿名类型中,该类型具有两个属性:Value
和Index
;Aggregate
将得到Value
最高的元素;1.最后,我们得到所选元素的
Index
。**在
Select
期间分配大量新对象可能是浪费的。正如一些人测试的那样,它在大列表中表现不佳。**EDIT 1:**增加空列表检查。
**编辑2:**增加了关于性能的警告。
toiithl63#
这里有一个自定义的LINQ方法,我相信它可以满足您的需求。(我以前有另一个做投影的,但你可以只调用Select来做,因为你只需要索引。
63lcw9qa4#
下面是如何使用LINQ在一个(长)行中完成此操作,只需一次遍历集合。它应该适用于任何
IEnumerable<int>
,而不仅仅是列表。下面是上面的非LINQ等价物,使用
foreach
循环。(同样,只需一次遍历集合,并且应该适用于任何IEnumerable<int>
。如果你知道集合是一个
IList<int>
,那么简单的for
循环可能是最简单的解决方案:7kqas0il5#
我无法改进Jon Skeet对一般情况的回答,所以我将在int列表的特定情况下获得“高性能”奖。
gopyfrb36#
以下是我的解决方案:
pvabu6sv7#
如果你喜欢,这里是非linq方法:
这至少是一次遍历列表。
希望这能帮上忙
凯尔
mfuanj7w8#
使用自定义函数,使用Max()和IndexOf()会花费更多。
q35jwt9p9#
简化.