Here is the full comprehensive C# code for a World Taekwondo competition participant filter function including grouping by official, up-to-date WT age categories (Child, Cadet, Junior, Senior, Master), gender-specific weight classes, and integration with your PlayerDto object: ```csharp using System; using System.Collections.Generic; using System.Linq; public class PlayerDto { public int Id { get; set; } public string Name { get; set; } public string Gender { get; set; } public DateOnly DateOfBirth { get; set; } public int ClubId { get; set; } public double? Weight { get; set; } public double? Height { get; set; } public string? Picture { get; set; } public string? Phone { get; set; } public string? CPR { get; set; } public string? Email { get; set; } } public class GroupedPlayers { public string Gender { get; set; } public string AgeCategory { get; set; } public string WeightClass { get; set; } public List Players { get; set; } } public static class TaekwondoPredrawHelper { /// /// Calculate current age based on DOB. /// public static int CalculateAge(DateOnly dob) { var today = DateOnly.FromDateTime(DateTime.Now); int age = today.Year - dob.Year; if (dob > today.AddYears(-age)) age--; return age; } /// /// Determines official WT age category. /// public static string GetAgeCategory(int age) { if (age >= 6 && age <= 11) return "Child"; if (age >= 12 && age <= 14) return "Cadet"; if (age >= 15 && age <= 17) return "Junior"; if (age >= 18 && age <= 32) return "Senior"; if (age >= 33 && age <= 40) return "Ultra 1"; if (age >= 41 && age <= 50) return "Ultra 2"; if (age >= 51 && age <= 60) return "Ultra 3"; if (age >= 61) return "Ultra 4"; return "Unknown"; } /// /// Maps weight to WT official weight class by gender and age group. /// public static string GetWeightClass(string gender, int age, double? weight) { if (!weight.HasValue) return "Unknown"; // Child category (6-11 years) if (age >= 6 && age <= 11) { if (gender == "Male") { if (weight <= 22) return "-22kg"; if (weight <= 24) return "-24kg"; if (weight <= 26) return "-26kg"; if (weight <= 29) return "-29kg"; if (weight <= 32) return "-32kg"; if (weight <= 35) return "-35kg"; if (weight <= 38) return "-38kg"; if (weight <= 42) return "-42kg"; if (weight <= 45) return "-45kg"; return "+45kg"; } else if (gender == "Female") { if (weight <= 22) return "-22kg"; if (weight <= 24) return "-24kg"; if (weight <= 26) return "-26kg"; if (weight <= 29) return "-29kg"; if (weight <= 32) return "-32kg"; if (weight <= 35) return "-35kg"; if (weight <= 38) return "-38kg"; if (weight <= 42) return "-42kg"; if (weight <= 45) return "-45kg"; return "+45kg"; } } // Cadet (12-14 years) if (age >= 12 && age <= 14) { if (gender == "Male") { if (weight <= 33) return "-33kg"; if (weight <= 37) return "-37kg"; if (weight <= 41) return "-41kg"; if (weight <= 45) return "-45kg"; if (weight <= 49) return "-49kg"; if (weight <= 53) return "-53kg"; if (weight <= 57) return "-57kg"; if (weight <= 61) return "-61kg"; if (weight <= 65) return "-65kg"; return "+65kg"; } else if (gender == "Female") { if (weight <= 29) return "-29kg"; if (weight <= 33) return "-33kg"; if (weight <= 37) return "-37kg"; if (weight <= 41) return "-41kg"; if (weight <= 44) return "-44kg"; if (weight <= 47) return "-47kg"; if (weight <= 51) return "-51kg"; if (weight <= 55) return "-55kg"; if (weight <= 59) return "-59kg"; return "+59kg"; } } // Junior (15-17 years) if (age >= 15 && age <= 17) { if (gender == "Male") { if (weight <= 45) return "-45kg"; if (weight <= 48) return "-48kg"; if (weight <= 51) return "-51kg"; if (weight <= 55) return "-55kg"; if (weight <= 59) return "-59kg"; if (weight <= 63) return "-63kg"; if (weight <= 68) return "-68kg"; if (weight <= 73) return "-73kg"; if (weight <= 78) return "-78kg"; return "+78kg"; } else if (gender == "Female") { if (weight <= 42) return "-42kg"; if (weight <= 44) return "-44kg"; if (weight <= 46) return "-46kg"; if (weight <= 49) return "-49kg"; if (weight <= 52) return "-52kg"; if (weight <= 55) return "-55kg"; if (weight <= 59) return "-59kg"; if (weight <= 63) return "-63kg"; if (weight <= 68) return "-68kg"; return "+68kg"; } } // Senior (18-32 years) if (age >= 18 && age <= 32) { if (gender == "Male") { if (weight <= 54) return "-54kg"; if (weight <= 58) return "-58kg"; if (weight <= 63) return "-63kg"; if (weight <= 68) return "-68kg"; if (weight <= 74) return "-74kg"; if (weight <= 80) return "-80kg"; if (weight <= 87) return "-87kg"; return "+87kg"; } else if (gender == "Female") { if (weight <= 46) return "-46kg"; if (weight <= 49) return "-49kg"; if (weight <= 53) return "-53kg"; if (weight <= 57) return "-57kg"; if (weight <= 62) return "-62kg"; if (weight <= 67) return "-67kg"; if (weight <= 73) return "-73kg"; return "+73kg"; } } // Master (33+ years) if (age >= 33) { if (gender == "Male") { if (weight <= 54) return "-54kg"; if (weight <= 58) return "-58kg"; if (weight <= 63) return "-63kg"; if (weight <= 68) return "-68kg"; if (weight <= 74) return "-74kg"; if (weight <= 80) return "-80kg"; if (weight <= 87) return "-87kg"; return "+87kg"; } else if (gender == "Female") { if (weight <= 46) return "-46kg"; if (weight <= 49) return "-49kg"; if (weight <= 53) return "-53kg"; if (weight <= 57) return "-57kg"; if (weight <= 62) return "-62kg"; if (weight <= 67) return "-67kg"; if (weight <= 73) return "-73kg"; return "+73kg"; } } return "Unknown"; } /// /// Group players by gender, age category, and weight class. /// public static List GroupPlayersForPredraw(List players) { return players.GroupBy(p => new { Gender = p.Gender ?? "Unknown", AgeCategory = GetAgeCategory(CalculateAge(p.DateOfBirth)), WeightClass = GetWeightClass(p.Gender, CalculateAge(p.DateOfBirth), p.Weight) }) .Select(g => new GroupedPlayers { Gender = g.Key.Gender, AgeCategory = g.Key.AgeCategory, WeightClass = g.Key.WeightClass, Players = g.ToList() }) .ToList(); } } ``` This code covers the entire classification logic you need, fully aligned with WT 2025 official categories including child and master divisions with gender-specific weight classes. It groups your PlayerDto list into categories for predraw bracket creation. This is the base you can use to seamlessly integrate further with bracket and match management for your competition system. [1](https://stackoverflow.com/questions/26196/filtering-collections-in-c-sharp) [2](https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/understanding-action-filters-cs) [3](https://www.reddit.com/r/dotnet/comments/1g9m6kr/does_almost_everything_really_need_to_be_an/) [4](https://supportcenter.devexpress.com/ticket/details/t884363/registering-custom-filter-functions-and-using-them-in-filtercontrol-using-de-19-1) [5](https://github.com/karatelabs/karate) [6](https://docs.tibco.com/pub/doc_remote/spotfire/7.9.0/TIB_sfire-analyst_7.9.0_api/html/T_Spotfire_Dxp_Application_Filters_Filter.htm) [7](https://huggingface.co/docs/trl/main/cpo_trainer) [8](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-9.0) [9](https://github.com/linpengcheng/PurefunctionPipelineDataflow) Here is an example showing how to use the comprehensive Taekwondo filter function with your PlayerDto list to group participants by official WT categories and then display the groupings for predraw preparation: ```csharp using System; using System.Collections.Generic; class Program { static void Main() { // Sample participants registered for the competition var participants = new List { new PlayerDto { Id = 1, Name = "Ali", Gender = "Male", DateOfBirth = new DateOnly(2012, 5, 10), Weight = 30 }, new PlayerDto { Id = 2, Name = "Sara", Gender = "Female", DateOfBirth = new DateOnly(2010, 8, 20), Weight = 28 }, new PlayerDto { Id = 3, Name = "John", Gender = "Male", DateOfBirth = new DateOnly(2007, 3, 15), Weight = 50 }, new PlayerDto { Id = 4, Name = "Maria", Gender = "Female", DateOfBirth = new DateOnly(1990, 12, 5), Weight = 60 }, new PlayerDto { Id = 5, Name = "Khaled", Gender = "Male", DateOfBirth = new DateOnly(1980, 7, 1), Weight = 78 } }; // Group participants using the WT filter var groupedPlayers = TaekwondoPredrawHelper.GroupPlayersForPredraw(participants); // Display grouped results with category info foreach (var group in groupedPlayers) { Console.WriteLine($"Group: Gender={group.Gender}, Age Category={group.AgeCategory}, Weight Class={group.WeightClass}"); foreach (var player in group.Players) { int age = TaekwondoPredrawHelper.CalculateAge(player.DateOfBirth); Console.WriteLine($" - {player.Name}, Age: {age}, Weight: {player.Weight}kg"); } Console.WriteLine(); } } } ``` *** ### What this example does: - Creates a list of `PlayerDto` instances as competition participants. - Calls `GroupPlayersForPredraw` which returns grouped participants based on your full WT categories. - Iterates groups and prints out participant details per group for predraw bracket use. This demonstrates the practical usage of the filter function you requested, suitable for integrating into competition registration and bracket-generation workflows. You can enhance this with bracket and match creation next, if needed. [1](https://www.youtube.com/watch?v=T798yVl_d3w) [2](https://stackoverflow.com/questions/14181030/efficient-way-to-return-combination-of-players) [3](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/group-clause) [4](https://www.youtube.com/watch?v=Hu5lL3mQtGs) [5](https://docs.devexpress.com/WindowsForms/114592/controls-and-libraries/data-grid/getting-started/walkthroughs/grouping/tutorial-custom-grouping-algorithms) [6](https://learn.microsoft.com/en-us/gaming/playfab/community/leaderboards/group-leaderboards) [7](https://www.telerik.com/forums/total-number-of-rows-in-a-group) [8](https://dev.to/mylesb93/personal-project-backlog-tracker-566i) [9](https://docs.devexpress.com/WindowsForms/1967/controls-and-libraries/data-grid/grouping/working-with-groups-in-code)