给出这样一个清单:
List<int> intList = new List<int>();
intList.Add(5);
intList.Add(10);
intList.Add(15);
intList.Add(46);
Run Code Online (Sandbox Code Playgroud)
你如何获得列表中最大元素的索引?在这种情况下,它在索引3处.
编辑:遗憾的是标准LINQ没有提供这些功能.
Sad*_*egh 37
这条路 :
var maxIndex = foo.IndexOf(foo.Max());
Run Code Online (Sandbox Code Playgroud)
jpb*_*chi 16
这是一个简单*且相对有效的**解决方案:
int indexMax
= !intList.Any() ? -1 :
intList
.Select( (value, index) => new { Value = value, Index = index } )
.Aggregate( (a, b) => (a.Value > b.Value) ? a : b )
.Index;
Run Code Online (Sandbox Code Playgroud)
在!intList.Any() ? -1 :将迫使-1如果列表是空的;
在Select将项目中的每个int元素为一个匿名类型具有两个属性:Value和Index;
该Aggregate会得到最高的元素Value;
最后,我们得到Index了所选元素.
*简单是相对的.这里的目的是达到可读性的平衡,并且仍然只扫描列表一次.
**在此期间分配大量新对象Select可能是浪费.有些人测试过,它对大型列表表现不佳.
编辑1:添加空列表检查.
编辑2:增加了关于性能的警告.
Jon*_*eet 12
这是一个自定义的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;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是使用LINQ在一条(长)行中执行此操作的方法,只需一次通过集合即可.它应该适用于任何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
);
Run Code Online (Sandbox Code Playgroud)
这是使用foreach循环的上述非LINQ等价物.(再次,只需一次通过集合,并应该适用于任何IEnumerable<int>.)
int maxIndex = -1, maxValue = int.MinValue, i = 0;
foreach (int v in intList)
{
if ((maxIndex < 0) || (v > maxValue))
{
maxValue = v;
maxIndex = i;
}
i++;
}
Run Code Online (Sandbox Code Playgroud)
如果您知道该集合是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;
}
}
Run Code Online (Sandbox Code Playgroud)