A cool new feature in .NET is the ability to get max and min values from a set of complex objects, using a common property in those objects. Let's see how to do that in this post!
Current Implementation
LINQ in .NET 5 and earlier contained a group of functions that allows us to get the maximum or minimum in a set of values.
var numbers = new List<int>() { 5, 19, 6, 2, 24, 9, 7 };
var max = numbers.Max(); //24
var min = numbers.Min(); //2
This was great if you were only dealing with simple or primitive values. However, it wasn't much use for complex collections of classes. .NET 6 makes that situation much easier with the introduction of MaxBy()
and MinBy()
methods.
New Implementation
In .NET 6, we can use the new MaxBy()
and MinBy()
methods to find an object with the maximum value in a set.
Let's say we have the following User
class, and a collection of User
objects.
public class User
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class LINQSetByExamples
{
private List<User> GetUserList()
{
return new List<User>()
{
new User()
{
ID = 1,
FirstName = "Terrance",
LastName = "Johnson",
DateOfBirth = new DateTime(1985, 12, 6)
},
new User()
{
ID = 2,
FirstName = "Angelica",
LastName = "Johnson",
DateOfBirth = new DateTime(1984, 8, 22)
},
new User()
{
ID = 3,
FirstName = "Jackson",
LastName = "Browne",
DateOfBirth = new DateTime(2001, 7, 29)
},
new User()
{
ID = 4,
FirstName = "Hailee",
LastName = "Escobar",
DateOfBirth = new DateTime(2004, 1, 16)
}
};
}
}
By looking at this collection of User
objects, we can answer questions like "who is the youngest/oldest user in the set?". With .NET 6 and MaxBy()
, we can now programmatically answer that question.
public void Examples()
{
List<User> users = GetUserList();
var youngestPerson = users.MaxBy(x => x.DateOfBirth.Year); //Hailee Escobar
}
What MaxBy()
does is find the maximum value for a given property of an object. In this case, we are specifying DateOfBirth.Year
as the parameter for MaxBy()
, so the method finds the object with the largest DateOfBirth.Year
value, which is also the youngest person in the collection.
Similarly, MinBy()
finds the object with the smallest value for the specified property. We could use it, trivially, to find the oldest person in the set:
public void Examples()
{
//Angelica Johnson
var youngestBornBefore1995 = users.MaxBy(x => x.DateOfBirth.Year);
}
We could also use it in a more complex manner. Say we want not the youngest user in the set, but rather the youngest user born before 1995. For that, we need only add a Where()
clause:
public void Examples()
{
//Terrance Johnson
var youngestBornBefore1995 = users.Where(x=>x.DateOfBirth.Year < 1995)
.MaxBy(x => x.DateOfBirth.Year);
}
Because both MaxBy()
and MinBy()
find objects by ordering them by a property, we could use them to find other kinds of users. For example, we could find the first person when ordering the list by last name alphabetically:
public void Examples()
{
//Jackson Browne
var firstPersonAlphaByLastName = users.MinBy(x => x.LastName);
}
Demo Project
As with all posts in this series, there is a demo project you can check out over on GitHub that shows examples of LINQ's Chunk()
method and its behavior. Check it out!
Happy Coding!