C#中字典的遍历方法
技术背景
在C#编程中,Dictionary<TKey, TValue>
是一种常用的数据结构,它提供了键值对的存储方式。在实际开发中,我们经常需要遍历字典中的元素,以获取键或值进行相应的操作。然而,不同的遍历方式在性能、可读性和适用性上有所差异。
实现步骤
1. 使用 foreach
遍历键值对
1 2 3 4
| foreach(KeyValuePair<string, string> entry in myDictionary) { }
|
也可以使用 var
关键字简化:
1 2 3 4 5
| foreach(var item in myDictionary) { foo(item.Key); bar(item.Value); }
|
2. 仅遍历键
1 2 3 4
| foreach(var item in myDictionary.Keys) { foo(item); }
|
3. 仅遍历值
1 2 3 4
| foreach(var item in myDictionary.Values) { foo(item); }
|
4. 使用 for
循环结合 ElementAt
方法(需要计数器时)
1 2 3 4 5
| for (int index = 0; index < dictionary.Count; index++) { var item = dictionary.ElementAt(index); var itemKey = item.Key; var itemValue = item.Value; }
|
5. 使用LINQ指定排序顺序遍历
1 2 3 4
| foreach (var kvp in items.OrderBy(kvp => kvp.Key)) { }
|
仅遍历排序后的值:
1 2 3 4
| foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value)) { doStuff(item); }
|
6. 使用解构器(C# 7.0及以上)
1 2 3 4
| var dic = new Dictionary<int, string>() { { 1, "One" }, { 2, "Two" }, { 3, "Three" } }; foreach (var (key, value) in dic) { Console.WriteLine($"Item [{key}] = {value}"); }
|
7. 使用 AsParallel
进行多线程处理(适用于大数据集)
1 2 3 4 5 6
| dictionary .AsParallel() .ForAll(pair => { });
|
8. 使用 ToList().ForEach
方法
1 2 3 4 5 6
| Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>(); myProductPrices.ToList().ForEach(kvP => { kvP.Value *= 1.15; Console.WriteLine(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value)); });
|
核心代码
以下是几种遍历方式的完整示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| using System; using System.Collections.Generic; using System.Linq;
class Program { static void Main() { Dictionary<string, string> myDictionary = new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" }, { "key3", "value3" } };
foreach (var kvp in myDictionary) { Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}"); }
foreach (var key in myDictionary.Keys) { Console.WriteLine($"Key: {key}"); }
foreach (var value in myDictionary.Values) { Console.WriteLine($"Value: {value}"); }
foreach (var kvp in myDictionary.OrderBy(kvp => kvp.Key)) { Console.WriteLine($"Sorted Key: {kvp.Key}, Value: {kvp.Value}"); }
foreach (var (key, value) in myDictionary) { Console.WriteLine($"Deconstructed Key: {key}, Value: {value}"); } } }
|
最佳实践
- 性能优先:如果对性能要求较高,避免不必要的转换和操作。例如,直接使用
foreach
遍历键值对通常比先获取键再进行查找更快。 - 可读性优先:使用解构器或
var
关键字可以提高代码的可读性,使代码更简洁。 - 特定需求:如果需要按特定顺序遍历,可以使用 LINQ 的
OrderBy
方法;如果处理大数据集,可以考虑使用 AsParallel
进行多线程处理。
常见问题
1. 遍历字典时修改字典会有什么问题?
在使用 foreach
遍历字典时,不能修改字典的结构(添加或删除元素),否则会抛出 InvalidOperationException
异常。如果需要修改字典,可以使用 ToList().ForEach
或其他方法。
2. 不同遍历方式的性能差异有多大?
一般来说,直接使用 foreach
遍历键值对的性能较好。而先获取键再进行查找的方式性能相对较差。但具体性能差异还与数据量、数据类型等因素有关。在实际开发中,可以进行性能测试来选择合适的遍历方式。
3. 字典的遍历顺序是怎样的?
Dictionary<TKey, TValue>
不保证元素的遍历顺序,它的元素顺序取决于添加元素的顺序和内部哈希算法。如果需要有序的键值对集合,可以使用 SortedList<TKey, TValue>
或 SortedDictionary<TKey, TValue>
。