I have a list of objects that have two int properties. The list is the output of another linq query. The object:
public class DimensionPair { public int Height { get; set; } public int Width { get; set; } }
I want to find and return the object in the list which has the largest Height
property value.
I can manage to get the highest value of the Height
value but not the object itself.
Can I do this with Linq? How?
In LINQ, you can find the maximum element of the given sequence by using Max() function. This method provides the maximum element of the given set of values. It does not support query syntax in C#, but it supports in VB.NET. It is available in both Enumerable and Queryable classes in C#.
How to get the max value in a list in R? First, use the unlist() function to convert the list into a vector, and then use the max() function to get the maximum value. The following are the arguments that you can give to the max() function in R. x – The vector for which you want to compute the max value.
We have an extension method to do exactly this in MoreLINQ. You can look at the implementation there, but basically it's a case of iterating through the data, remembering the maximum element we've seen so far and the maximum value it produced under the projection.
In your case you'd do something like:
var item = items.MaxBy(x => x.Height);
This is better (IMO) than any of the solutions presented here other than Mehrdad's second solution (which is basically the same as MaxBy
):
Max
value and then finding the first element with that value is O(n), but iterates over the sequence twice. Where possible, you should use LINQ in a single-pass fashion.This would require a sort (O(n log n)) but is very simple and flexible. Another advantage is being able to use it with LINQ to SQL:
var maxObject = list.OrderByDescending(item => item.Height).First();
Note that this has the advantage of enumerating the list
sequence just once. While it might not matter if list
is a List<T>
that doesn't change in the meantime, it could matter for arbitrary IEnumerable<T>
objects. Nothing guarantees that the sequence doesn't change in different enumerations so methods that are doing it multiple times can be dangerous (and inefficient, depending on the nature of the sequence). However, it's still a less than ideal solution for large sequences. I suggest writing your own MaxObject
extension manually if you have a large set of items to be able to do it in one pass without sorting and other stuff whatsoever (O(n)):
static class EnumerableExtensions { public static T MaxObject<T,U>(this IEnumerable<T> source, Func<T,U> selector) where U : IComparable<U> { if (source == null) throw new ArgumentNullException("source"); bool first = true; T maxObj = default(T); U maxKey = default(U); foreach (var item in source) { if (first) { maxObj = item; maxKey = selector(maxObj); first = false; } else { U currentKey = selector(item); if (currentKey.CompareTo(maxKey) > 0) { maxKey = currentKey; maxObj = item; } } } if (first) throw new InvalidOperationException("Sequence is empty."); return maxObj; } }
and use it with:
var maxObject = list.MaxObject(item => item.Height);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With