如何获取LINQ以返回集合中具有最大值的对象的索引? [英] How can I get LINQ to return the index of the object which has the max value in a collection?

查看:61
本文介绍了如何获取LINQ以返回集合中具有最大值的对象的索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a list of immutable objects (in my specific case a list of Tuple<double, double>) and I'd like to change the one with the highest Item2 value.

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

Ideally there would be an IndexOfMaxBy function I could use, so I could do:

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

var original = myList[indexOfPointWithHighestItem2];

myList[indexOfPointWithHighestItem2] = 
  new Tuple<double, double>(original.Item1, original.Item2 - 1);

我看过乔恩·斯基特(Jon Skeet)的MaxBy函数与Select结合使用,我可以做到:

I have seen How can I get LINQ to return the object which has the max value for a given property?, and using Jon Skeet's MaxBy function combined with Select I could do:

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

但这会为列表中的每个对象创建一个新对象,并且必须有一种更整洁的方法.有人有什么好的建议吗?

But this creates a new object for every object in my list, and there must be a neater way. Does anyone have any good suggestions?

推荐答案

如果愿意,您当然可以自己编写IndexOfMaxBy扩展名.

Well, if you wanted to, you could of course write an IndexOfMaxByextension yourself.

示例(未经测试):

public static int IndexOfMaxBy<TSource, TProjected>
    (this IEnumerable<TSource> source,
     Func<TSource, TProjected> selector,
     IComparer<TProjected> comparer = null
    )
{

    //null-checks here

    using (var erator = source.GetEnumerator())
    {
        if (!erator.MoveNext())
            throw new InvalidOperationException("Sequence is empty.");

        if (comparer == null)
            comparer = Comparer<TProjected>.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);

这篇关于如何获取LINQ以返回集合中具有最大值的对象的索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆