我已经看到了几种不同的方法来迭代C#中的字典。有标准的方法吗?
我已经看到了几种不同的方法来迭代C#中的字典。有标准的方法吗?
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
如果您尝试在C#中使用通用字典,则可以使用另一种语言的关联数组:
foreach(var item in myDictionary)
{
foo(item.Key);
bar(item.Value);
}
或者,如果您只需要遍历密钥集合,请使用
foreach(var item in myDictionary.Keys)
{
foo(item);
}
最后,如果你只对价值感兴趣:
foreach(var item in myDictionary.Values)
{
foo(item);
}
(注意那个 var
keyword是一个可选的C#3.0及以上功能,你也可以在这里使用你的键/值的确切类型)
在某些情况下,您可能需要一个可以通过for循环实现提供的计数器。为此,LINQ提供 ElementAt
这使得以下内容:
for (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
取决于你是否在关键或价值观之后......
来自MSDN Dictionary(TKey, TValue)
课程描述:
// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
Console.WriteLine("Key = {0}, Value = {1}",
kvp.Key, kvp.Value);
}
// To get the values alone, use the Values property.
Dictionary<string, string>.ValueCollection valueColl =
openWith.Values;
// The elements of the ValueCollection are strongly typed
// with the type that was specified for dictionary values.
Console.WriteLine();
foreach( string s in valueColl )
{
Console.WriteLine("Value = {0}", s);
}
// To get the keys alone, use the Keys property.
Dictionary<string, string>.KeyCollection keyColl =
openWith.Keys;
// The elements of the KeyCollection are strongly typed
// with the type that was specified for dictionary keys.
Console.WriteLine();
foreach( string s in keyColl )
{
Console.WriteLine("Key = {0}", s);
}
一般来说,在没有特定背景的情况下询问“最好的方式”就像问什么是最好的颜色。
一方面,有很多颜色,没有最好的颜色。这取决于需要,也经常取决于口味。
另一方面,有许多方法可以在C#中迭代一个Dictionary而且没有最好的方法。这取决于需要,也经常取决于口味。
foreach (var kvp in items)
{
// key is kvp.Key
doStuff(kvp.Value)
}
如果您只需要该值(允许调用它) item
,比可读性更强 kvp.Value
)。
foreach (var item in items.Values)
{
doStuff(item)
}
通常,初学者对词典枚举的顺序感到惊讶。
LINQ提供了一种简洁的语法,允许指定顺序(和许多其他东西),例如:
foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
// key is kvp.Key
doStuff(kvp.Value)
}
您可能只需要该值。 LINQ还提供简洁的解决方案:
item
,比可读性更强 kvp.Value
)这里是:
foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
doStuff(item)
}
您可以从这些示例中获得更多真实用例。 如果您不需要特定订单,只需坚持“最直接的方式”(见上文)!
我会说foreach是标准的方式,虽然它显然取决于你在寻找什么
foreach(var kvp in my_dictionary) {
...
}
这就是你要找的东西吗?
您也可以在大字典上尝试使用多线程处理。
dictionary
.AsParallel()
.ForAll(pair =>
{
// Process pair.Key and pair.Value here
});
有很多选择。我最喜欢的是KeyValuePair
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary)
{
// Do some interesting things
}
您还可以使用键和值集合
我很欣赏这个问题已经有了很多回复,但我想进行一些研究。
与迭代类似数组的东西相比,迭代字典可能相当慢。在我的测试中,对数组的迭代花费了0.015003秒,而对字典的迭代(具有相同数量的元素)花费了0.0365073秒,这是2.4倍的长度!虽然我看到了更大的差异。为了比较,List介于0.00215043秒之间。
然而,这就像比较苹果和橘子。我的观点是迭代字典很慢。
字典针对查找进行了优化,因此考虑到这一点,我创建了两种方法。一个只是做一个foreach,另一个迭代键然后查找。
public static string Normal(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var kvp in dictionary)
{
value = kvp.Value;
count++;
}
return "Normal";
}
这个加载密钥并迭代它们(我也尝试将密钥拉成字符串[]但差别可以忽略不计。
public static string Keys(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var key in dictionary.Keys)
{
value = dictionary[key];
count++;
}
return "Keys";
}
在这个例子中,正常的foreach测试花了0.0310062,密钥版本花了0.2205441。加载所有键并迭代所有查找显然要慢得多!
对于最后的测试,我已经执行了十次迭代,看看在这里使用密钥是否有任何好处(此时我只是好奇):
这是RunTest方法,如果这可以帮助您可视化正在发生的事情。
private static string RunTest<T>(T dictionary, Func<T, string> function)
{
DateTime start = DateTime.Now;
string name = null;
for (int i = 0; i < 10; i++)
{
name = function(dictionary);
}
DateTime end = DateTime.Now;
var duration = end.Subtract(start);
return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);
}
正常的foreach运行时间为0.2820564秒(大约是单次迭代的十倍 - 正如您所期望的那样)。密钥的迭代花了2.2249449秒。
编辑添加: 阅读其他一些答案让我怀疑如果我使用Dictionary而不是Dictionary,会发生什么。在此示例中,数组占用0.0120024秒,列表0.0185037秒,字典0.0465093秒。期望数据类型对字典的缓慢程度产生影响是合理的。
我的结论是什么??
您建议在下面进行迭代
Dictionary<string,object> myDictionary = new Dictionary<string,object>();
//Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary) {
//Do some interesting things;
}
仅供参考, foreach
如果值是object类型,则不起作用。
同 .NET Framework 4.7
一个人可以使用 分解
var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
Console.WriteLine(fruit + ": " + number);
}
要使此代码适用于较低的C#版本,请添加 System.ValueTuple NuGet package
并在某处写
public static class MyExtensions
{
public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple,
out T1 key, out T2 value)
{
key = tuple.Key;
value = tuple.Value;
}
}