一尘不染

如何使用LINQ获取数组中最大值的索引?

c#

我有一个双精度数组,我想要最高值的索引。到目前为止,我已经提出了这些解决方案,但是我认为必须有一个更优雅的解决方案。有想法吗?

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();

阅读 854

收藏
2020-05-19

共1个答案

一尘不染

我建议编写自己的扩展方法(编辑为带有IComparable<T>约束的通用方法。)

public static int MaxIndex<T>(this IEnumerable<T> sequence)
    where T : IComparable<T>
{
    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。

一句话就特点:

  • 这适用于只能枚举一次的序列-这有时可能非常重要,并且通常是IMO的理想功能。
  • 内存复杂度为O(1)(与O(n)进行排序相反)
  • 运行时复杂度为O(n)(与O(n log n)进行排序相反)

至于是否是“
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();

它太可怕了,我不建议您完全使用它-但它可以工作。

2020-05-19