在 Linq 中从 Select 查询中找到索引

4

我正在尝试找到在List<>中两个属性之间的差异达到max时的index。目前,我使用下面的LINQ查询来找到max

var result = link.Select(x => Math.Abs(x.Prop1 - x.Prop2)).Max();

我该如何获取索引?

4个回答

5
var result = 
     link.Select((x, i) => new { value = Math.Abs(x.Prop1 - x.Prop2), index = i })
          .OrderByDescending(x=>x.value)
          .FirstOrDefault();

var indexValue = result?.index;
var maxValue = result?.value;

这里正在运作。


谢谢。所以,OrderByDescendingFirst的组合替换了Max()?为什么我不能使用Max找到索引? - hello
1
@hello 在 select 返回的对象应该继承 IComparable 接口,并且你需要构建内部逻辑来确定你将如何取得它的最大值,最大值是什么。之后你可以调用这个对象的索引。但是这样做会很麻烦而没有意义。 - mybirthname

2

如果您有大量的数据,您可能会担心这些方法在获得结果之前创建2个额外的数据集。您可以使用from语句只生成一个额外的数据集:

int index = (from i in Enumerable.Range(0, link.Count)
             orderby Math.Abs(link.Prop1 - link.Prop2)
             select new { index = i, value = link[i] }).First().index;

或者使用普通的for循环而不创建任何额外的集合:

int max = 0;
int indx = 0;
for(int i = 0; i < link.Count;i++)
{
    int temp = Math.Abs(link.Prop1 - link.Prop2);
    if (temp > max)
    {
        max = temp;
        indx = i;
    }
}

2
以下是使用Max的工作版本,需要实现Icomparable<T>代码使用LinqPad创建,包含一些测试数据以进行验证)。
void Main()
{
    List<Test> link = Test.FetchList();

    var result = link.Select((x, i) => new { x.Prop1, x.Prop2, index = i })
                     .Max(y => new Result {value = Math.Abs(y.Prop1 - y.Prop2), index = y.index});

    result.Dump(); // In this case result would be index 2

}

public class Test
{
    public int Prop1 { get; set;}

    public int Prop2 { get; set;}

    public static List<Test> FetchList()
    {
      var returnList = new List<Test>();

        returnList.Add(new Test { Prop1 = 1, Prop2 = -5});
        returnList.Add(new Test { Prop1 = 2, Prop2 = -5});
        returnList.Add(new Test { Prop1 = 1, Prop2 = -9});
        returnList.Add(new Test { Prop1 = 3, Prop2 = -2});
        returnList.Add(new Test { Prop1 = 21, Prop2 = 15});

      return (returnList);
    }

}

public class Result : IComparable<Result>
{
    public int value { get; set; }

    public int index { get; set; }

    public int CompareTo(Result other)
    {
       return (value - other.value);
    }
}

1
var r =  link
        .Select((x,idx)=>new{v = x, idx})
        .OrderBy(x=>Math.Abs(x.v.Prop2 - x.v.Prop1))
        .FirstOrDefault();

return r !=null ? r.idx : -1;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接