如何使用Linq从字典内的列表中高效获取多个值?
用LINQ简化代码并优化效率的方案
核心优化思路
原代码中每次遍历字典检查列表是否包含count的逻辑效率较低,且存在冗余操作。我们可以通过构建反向映射字典把int值直接关联到对应的columns枚举,将查找复杂度从O(n)降到O(1),同时用LINQ简化映射构建过程。
优化后的完整代码
public enum columns { Parts_Column, Questions_Column, Answers_Column, Reset_Amount }; public static void Main() { // 仅用于填充循环次数,无需实际使用元素 List<string> orderedRects = new List<string>() { "item1","item2","item3","item4","item5","item6","item7","item8","item9","item10" }; Dictionary<columns, List<int>> TheDictionary = new Dictionary<columns, List<int>>() { { columns.Parts_Column, new List<int>() { 1 } }, { columns.Questions_Column, new List<int>() { 2, 4 } }, { columns.Answers_Column, new List<int>() { 3, 5 } }, { columns.Reset_Amount, new List<int>() { 6 } } }; // 用LINQ构建反向映射:将int值映射到对应的columns枚举 var valueToColumnMap = TheDictionary .SelectMany(pair => pair.Value.Select(val => new { Value = val, Column = pair.Key })) .ToDictionary(entry => entry.Value, entry => entry.Column); int resetValue = TheDictionary[columns.Reset_Amount][0]; int count = 0; foreach (var _ in orderedRects) { // 简化count重置逻辑,用取模运算替代条件判断 count = count % resetValue; // 直接通过反向映射查找,效率更高 if (valueToColumnMap.TryGetValue(count, out var column)) { Console.WriteLine($"{column}: {count}"); } count++; } Console.WriteLine($"Total: {count}"); }
具体优化点说明
- 反向映射字典:通过
SelectMany将原字典的每个列表元素展开,再用ToDictionary构建int -> columns的映射,后续查找直接O(1)定位,避免每次遍历整个字典。 - 移除冗余操作:原代码中
Contains(count)确认存在后,又用Where(o => o == count).FirstOrDefault()获取值,完全没必要,直接使用count即可。 - 简化循环逻辑:遍历
orderedRects时不需要索引i,直接遍历元素更简洁;用count % resetValue替代条件判断重置count,代码更紧凑。 - 语法优化:使用集合初始化器创建字典,用字符串插值替代字符串拼接,提升代码可读性。
- 健壮性提升:用
TryGetValue替代直接索引,避免因意外情况导致的键不存在异常。
内容的提问来源于stack exchange,提问作者CJP
相关产品推荐
相关产品推荐

