当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何使用LINQ获取数组中最高值的索引?》经验,为你挑选了3个好方法。

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

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

Jon Skeet.. 44

我建议编写自己的扩展方法(编辑为带有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.

关于特点的一句话:

这适用于只能枚举一次的序列 - 这有时非常重要,并且通常是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();

这很可怕,我建议你不要使用它 - 但它会起作用.



1> Jon Skeet..:

我建议编写自己的扩展方法(编辑为带有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.

关于特点的一句话:

这适用于只能枚举一次的序列 - 这有时非常重要,并且通常是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();

这很可怕,我建议你不要使用它 - 但它会起作用.


@Pascal:你如何定义LINQ?对我来说,LINQ的一个好处是你可以添加自己的运算符,它们可以与预定义的运算符平滑地运行.编辑性能问题.

2> 小智..:

嗯,为什么要让它过于复杂?这是最简单的方法.

var indexAtMax = scores.ToList().IndexOf(scores.Max());

是的,您可以使用扩展方法来减少内存使用量,但除非您处理大型数组,否则您将永远不会注意到这种差异.


......也是最慢的....关于_never_通知:我们都注意到Windows很慢,尽管事实是"它是_not_处理巨大的阵列"

3> 小智..:
var scoreList = score.ToList();
int topIndex =
    (
      from x
      in score
      orderby x
      select scoreList.IndexOf(x)
    ).Last();

如果score不是一个数组,这不会是一半坏...


对于O(n)的操作,对列表(O(log(n))进行排序真的是一个很好的解决方案吗?
推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有