简体   繁体   中英

How to get the maximum item ordered by two fields using a Linq expression?

Is it possible to get result1 as a single linq expression? I understand that it may not be the best practise but I would just like to know how to do so out of curiousity.

result2 has a different answer but it correct too. However, it has a complexity of O(NlogN) as opposed to O(N).

void Main()
{
    A[] a = new A[4]{new A(0,0,0),new A(1,1,0),new A(1,2,1),new A(1,2,0)};
    /*
    //Grossly inefficient: replaced
    var tmpList = a.Where(x => (x.one == a.Max(y => y.one)));       
    var result1 = tmpList.First(x => (x.two == tmpList.Max(y => y.two)));
    */
    var maxOneValue = a.Max(x => x.one);
    var tmpList = a.Where(x => (x.one == maxOneValue));
    var maxTwoValueOfTmpList = tmpList.Max(x => x.two);
    var result1 = tmpList.First(x => (x.two == maxTwoValueOfTmpList));
    //A: 1, 2, 1

    var result2 = a.OrderBy(x => x.one)
              .ThenBy(x => x.two)
              .Last();
    //A: 1, 2, 0
}

class A 
{
    public int one;
    public int two;
    public int three;
    public A(int one, int two, int three)
    {
        this.one = one;
        this.two = two;
        this.three = three;
    }
}

edit: I have edited by question and hence some answers may not tally.

One way to do it is to implement IComparable<A> on your A class. Then your solution simply becomes:

var result1 = a.Max(); // 1,2,1

Here's how you would implement IComparable<A> :

class A : IComparable<A>
{
    ...

    public int CompareTo(A other)
    {

        return this.one == other.one ? this.two - other.two : this.one - other.one;
    }
}

Here is a demo: http://ideone.com/ufIcgf . The nice thing about this is that it still has a complexity of O(N) , and is also fairly concise.

也许这可以解决您的问题:

a.OrderBy(x => x.one + x.two).Last()

This query gives the same result :

var result = a.OrderByDescending(x => x.one + x.two)
                      .First();

But then you could get items without max 'one' field.. This one should work :

var result = a.OrderByDescending(x => x.two)
               .Where(x => (x.one == a.Max(y => y.one)))
               .First();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM