John Tan
John Tan

Reputation: 1385

Return the element of a list which fulfills a certain condition

I have a class:

class Point
{
    double X, Y;
}

From a List<Point>, say I want the Point where Point.X + Point.Y is maximum in the list. How would I do this in LINQ?

Upvotes: 5

Views: 532

Answers (4)

ptilton
ptilton

Reputation: 132

var maxValue = list.Max(m => m.X + m.Y);
var maxPoint = list.Where(p => p.X + p.Y == maxValue).FirstOrDefault();

for a highlander..

or

var largestPoints = list.Where(p => p.X + p.Y == maxValue);

for ties.

Upvotes: 0

aquinas
aquinas

Reputation: 23796

There's nothing out of the box. You could do:

Point theMax = null;
ForEach(x => theMax = (theMax == null || x.X + x.Y > theMax.X + theMax.Y ? x : theMax));

But obviously that's not very pretty.

What you really want is write your own extension method, and by write your own, I mean shamelessly steal MoreLinq's (https://code.google.com/p/morelinq/source/browse/MoreLinq/MaxBy.cs). You can also use: Install-Package MoreLinq.Source.MoreEnumerable.MaxBy

Then you can just do: var theMax = points.MaxBy(x => x.X + x.Y);

Remember, the beauty/power of Linq is that, at the end of the day, it's all extension methods. Don't forget that you can always write your own to do what you need. Of course, the MoreLinq project usually has what you need. It's a great library.

Upvotes: 0

sstan
sstan

Reputation: 36483

This would be one way (though not optimal by any means):

List<Point> list = ...;
Point maxPoint = list.OrderByDescending(p => p.X + p.Y).First();

Another way which should perform much better, would involve modifying your Point class to implement IComparable<T>, like this:

class Point : IComparable<Point>
{
    double X, Y;

    public int CompareTo(Point other)
    {
        return (X + Y).CompareTo(other.X + other.Y);
    }
}

... which would then allow you to simply do:

List<Point> list = ...;
Point maxPoint = list.Max();

Upvotes: 6

Enigmativity
Enigmativity

Reputation: 117064

I would add the Microsoft Reactive Team's Interactive Extensions (NuGet "Ix-Main"). They have a bunch of very useful IEnumerable<T> extensions.

This is the one you need:

Point max = points.MaxBy(p => p.X + p.Y).First();

Upvotes: 2

Related Questions