If I have a class that looks like:
public class Item
{
public int ClientID { get; set; }
public int ID { get; set; }
}
And a collection of those items...
List<Item> items = getItems();
How can I use LINQ to return the single "Item" object which has the highest ID?
If I do something like:
items.Select(i => i.ID).Max();
I'll only get the highest ID, when what I actually want returned is the Item object itself which has the highest ID? I want it to return a single "Item" object, not an int.
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#.
While the LINQ methods always return a new collection, they don't create a new set of objects: Both the input collection (customers, in my example) and the output collection (validCustomers, in my previous example) are just sets of pointers to the same objects.
By default, LINQ queries return a list of objects as an anonymous type. You can also specify that a query return a list of a specific type by using the Select clause.
The term "LINQ to Objects" refers to the use of LINQ queries with any IEnumerable or IEnumerable<T> collection directly, without the use of an intermediate LINQ provider or API such as LINQ to SQL or LINQ to XML. You can use LINQ to query any enumerable collections such as List<T>, Array, or Dictionary<TKey,TValue>.
This will loop through only once.
Item biggest = items.Aggregate((i1,i2) => i1.ID > i2.ID ? i1 : i2);
Thanks Nick - Here's the proof
class Program
{
static void Main(string[] args)
{
IEnumerable<Item> items1 = new List<Item>()
{
new Item(){ ClientID = 1, ID = 1},
new Item(){ ClientID = 2, ID = 2},
new Item(){ ClientID = 3, ID = 3},
new Item(){ ClientID = 4, ID = 4},
};
Item biggest1 = items1.Aggregate((i1, i2) => i1.ID > i2.ID ? i1 : i2);
Console.WriteLine(biggest1.ID);
Console.ReadKey();
}
}
public class Item
{
public int ClientID { get; set; }
public int ID { get; set; }
}
Rearrange the list and get the same result
.OrderByDescending(i=>i.id).First()
Regarding the performance concern, it is very likely that this method is theoretically slower than a linear approach. However, in reality, most of the time we are not dealing with the data set that is big enough to make any difference.
If performance is a main concern, Seattle Leonard's answer should give you linear time complexity. Alternatively, you may also consider to start with a different data structure that returns the max value item at constant time.
First()
will do the same as Take(1)
but returns the item directly instead of an enumeration containing the item.
int max = items.Max(i => i.ID);
var item = items.First(x => x.ID == max);
This assumes there are elements in the items collection of course.
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