In data analysis and reporting, it’s common to assign rankings to a dataset based on certain criteria. One common type of ranking is “dense rank,” which assigns unique ranks to each distinct item in the dataset, with no gaps between ranks for items with the same values. In this blog post, we’ll explore how to calculate dense rank in C# using LINQ, particularly when dealing with custom objects.
Understanding Dense Rank
Before we dive into the code, let’s briefly understand what dense rank is. Dense rank is a ranking method that assigns the same rank to items with equal values and then continues with the next rank without any gaps. For example, if you have a list of scores, dense rank will ensure that if two people have the same score, they both receive the same rank, and the next rank is assigned without any gaps.
Creating a Custom Object
We’ll start by creating a custom object for our example. In this case, we’ll create a Person
class with two properties: Name
and Score
. Our goal is to calculate the dense rank based on the Score
property of these objects.
class Person
{
public string Name { get; set; }
public int Score { get; set; }
}
Calculating Dense Rank
Now, let’s calculate the dense rank using LINQ. We’ll use LINQ to sort the list of Person
objects by score, group them by score, and then assign the ranks accordingly. Here’s the code:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
// Sample data with custom objects
var people = new List<Person>
{
new Person { Name = "Alice", Score = 100 },
new Person { Name = "Bob", Score = 85 },
new Person { Name = "Charlie", Score = 95 },
new Person { Name = "David", Score = 85 },
new Person { Name = "Eve", Score = 92 },
new Person { Name = "Frank", Score = 100 },
new Person { Name = "Grace", Score = 78 },
new Person { Name = "Hannah", Score = 92 },
new Person { Name = "Ivy", Score = 95 }
};
// Calculate dense rank using LINQ
var denseRank = people
.OrderByDescending(person => person.Score)
.GroupBy(person => person.Score)
.SelectMany((group, index) => group.Select(person => new { Person = person, Rank = index + 1 }))
.OrderBy(item => item.Rank)
.ToList();
// Display the result
foreach (var item in denseRank)
{
Console.WriteLine($"Name: {item.Person.Name}, Score: {item.Person.Score}, Dense Rank: {item.Rank}");
}
}
}
In this code, we start by ordering the list of Person
objects in descending order of their scores. We then group them by score and use SelectMany
to assign the dense rank. Finally, we display the result, which shows each person’s name, score, and dense rank.
Conclusion
Calculating dense rank in C# using LINQ is a useful technique when you need to assign ranks to items in a dataset, especially when dealing with custom objects. Understanding the principles of dense ranking allows you to handle tie-breaking scenarios effectively and provide clear and meaningful rankings for your data.
This example can be adapted for various ranking scenarios in your applications, providing you with a flexible tool for data analysis and reporting. Whether you’re working with scores, rankings, or any other ordered data, LINQ in C# can simplify the process of calculating dense ranks.