C# Convert a list to a dictionary
By FoxLearn 1/21/2025 6:34:56 AM 25
For example, using LINQ
using System.Linq; var employeeList = GetEmployeeList(); var employeesById = employeeList.ToDictionary(keySelector: e => e.Id, elementSelector: e => e);
This iterates through the list and applies the key and value selector lambdas you provide to construct the dictionary.
Using a Loop
If LINQ isn’t preferred, you can use a loop to achieve the same result:
var employees = GetEmployeeList(); var employeesById = new Dictionary<int, Employee>(); foreach (var employee in employees) { employeesById.Add(employee.Id, employee); }
This method typically has better performance compared to LINQ and might be preferred if performance is critical or LINQ is unfamiliar. Use whichever approach is more intuitive for your scenario.
Implicit Element Selector
These two statements produce the same result:
// Explicit element selector var employeesById = employeeList.ToDictionary(keySelector: e => e.Id, elementSelector: e => e); // Implicit element selector var employeesById = employeeList.ToDictionary(keySelector: e => e.Id);
If you omit the elementSelector
, the method defaults to using the list items as the values. This is often sufficient when indexing objects by one of their properties.
Handling Duplicate Keys
If the list contains duplicate keys, ToDictionary()
throws an ArgumentException
.
To address this, you can group the list by key and decide how to handle duplicates.
Aggregate a Value for Each Key
Suppose you want to count the number of employees per department:
var employees = new List<Employee> { new Employee { Id = 1, Department = "HR" }, new Employee { Id = 2, Department = "IT" }, new Employee { Id = 3, Department = "HR" } }; var employeeCountByDept = employees .GroupBy(e => e.Department) .ToDictionary(keySelector: g => g.Key, elementSelector: g => g.Count()); foreach (var deptCount in employeeCountByDept) { Console.WriteLine($"{deptCount.Key}={deptCount.Value}"); }
Output:
HR=2 IT=1
Store a List of Elements for Each Key
This example groups employees by department and stores all employees in that department:
var employeesByDept = employees .GroupBy(e => e.Department) .ToDictionary(keySelector: g => g.Key, elementSelector: g => g.ToList()); foreach (var dept in employeesByDept) { Console.WriteLine($"{dept.Key}={string.Join(", ", dept.Value.Select(e => e.Name))}"); }
Output:
HR=John, Jane IT=Alice
Select a First Element for Each Key
Sometimes, you only want the first employee per department:
var firstEmployeeByDept = employees .GroupBy(e => e.Department) .ToDictionary(keySelector: g => g.Key, elementSelector: g => g.First()); foreach (var dept in firstEmployeeByDept) { Console.WriteLine($"{dept.Key}={dept.Value.Name}"); }
Handling Duplicates in a Loop
For a manual approach, check for existing keys before adding to the dictionary:
var employeesByDept = new Dictionary<string, List<Employee>>(); foreach (var employee in employees) { if (!employeesByDept.ContainsKey(employee.Department)) { employeesByDept[employee.Department] = new List<Employee>(); } employeesByDept[employee.Department].Add(employee); } foreach (var dept in employeesByDept) { Console.WriteLine($"{dept.Key}={string.Join(", ", dept.Value.Select(e => e.Name))}"); }
Output:
HR=John, Jane IT=Alice
This approach may feel more straightforward than using LINQ in some cases.