DEV Community

Cover image for Two New LINQ Methods in .NET 9: CountBy and Index
Cesar Aguirre
Cesar Aguirre

Posted on • Originally published at canro91.github.io

Two New LINQ Methods in .NET 9: CountBy and Index

I originally posted this post on my blog a long time ago in a galaxy far, far away.


LINQ doesn't get new features with each release of the .NET framework. It simply works.

But this time, .NET 9 introduced two new LINQ methods: CountBy() and Index(). Let's take a look at them.

1. CountBy

CountBy groups the elements of a collection by a key and counts the occurrences of each key. With CountBy, there's no need to first group the elements of a collection to count its occurrences.

For example, let's count all movies in our catalog by release year, of course, using CountBy(),

var movies = new List<Movie>
{
    new Movie("Titanic", 1997, 4.5f),
    new Movie("The Fifth Element", 1997, 4.6f),
    new Movie("Forrest Gump", 1994, 4.3f),
    new Movie("Terminator 2", 1991, 4.7f),
    new Movie("Armageddon", 1998, 3.35f),
    new Movie("Platoon", 1986, 4),
    new Movie("My Neighbor Totoro", 1988, 5),
    new Movie("Pulp Fiction", 1994, 4.3f),
};

var countByReleaseYear = movies.CountBy(m => m.ReleaseYear);
//                              πŸ‘†πŸ‘†πŸ‘†
foreach (var (year, count) in countByReleaseYear)
{
    Console.WriteLine($"{year}: [{count}]");
}
// Output
// 1997: [2]
// 1994: [2]
// 1991: [1]
// 1998: [1]
// 1986: [1]
// 1988: [1]

record Movie(string Name, int ReleaseYear, float Rating);
Enter fullscreen mode Exit fullscreen mode

CountBy() returns a collection of KeyValuePair with the key in the first position and the count in the second one.

Before .NET 9.0, we needed to use GroupBy with a second parameter to transform each group, like this,

var countByReleaseYear = movies.GroupBy(
  x => x.ReleaseYear,
  (releaseYear, movies) => new
  // πŸ‘†πŸ‘†πŸ‘†
  {
      Year = releaseYear,
      Count = movies.Count()
      //      πŸ‘†πŸ‘†πŸ‘†
  });
Enter fullscreen mode Exit fullscreen mode

CountBy() has the same spirit of DistinctBy, MinBy, MaxBy, and other LINQ methods from .NET 6.0.

With these methods, we apply an action directly on a collection using a key selector. We don't need to filter or group a collection first to apply that action.

2. Index

Index projects every element of a collection alongside its position in the collection.

Let's "index" our catalog of movies,

var movies = new List<Movie>
{
    new Movie("Titanic", 1998, 4.5f),
    new Movie("The Fifth Element", 1997, 4.6f),
    new Movie("Terminator 2", 1991, 4.7f),
    new Movie("Avatar", 2009, 5),
    new Movie("Platoon", 1986, 4),
    new Movie("My Neighbor Totoro", 1988, 5)
};

foreach (var (index, movie) in movies.Index())
//                                    πŸ‘†πŸ‘†
{
    Console.WriteLine($"{index}: [{movie.Name}]");
}
// Output
// 0: [Titanic]
// 1: [The Fifth Element]
// 2: [Terminator 2]
// 3: [Avatar]
// 4: [Platoon]
// 5: [My Neighbor Totoro]

record Movie(string Name, int ReleaseYear, float Rating);
Enter fullscreen mode Exit fullscreen mode

Unlike CountBy(), Index() returns named tuples. It returns IEnumerable<(int Index, TSource Item)>.

Before, we had to use the Select() overload or roll our own extension method.

VoilΓ ! Those are two new LINQ methods in .NET 9.0: CountBy() and Index().

The .NET team is bringing to the standard library the methods we needed to roll ourselves before.


Want to write more expressive code for collections? Join my Udemy course, Getting Started with LINQ, and master everything you need to work productively with LINQ β€” all in less than two hours!

Top comments (2)

Collapse
 
rasheedmozaffar profile image
Rasheed K Mozaffar

Awesome examples, I'm looking forward to Index, which I'd want to use in many cases! Thanks for sharing πŸ™Œ

Collapse
 
canro91 profile image
Cesar Aguirre

Those two are great additions to LINQ...Happy coding!