Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 迭代字典的最佳方式是什么?_C#_Dictionary_Loops - Fatal编程技术网

C# 迭代字典的最佳方式是什么?

C# 迭代字典的最佳方式是什么?,c#,dictionary,loops,C#,Dictionary,Loops,我见过几种不同的方法来用C#迭代字典。有标准的方法吗?foreach(myDictionary中的KeyValuePair条目) { //对entry.Value或entry.Key执行某些操作 } 我想说,foreach是标准的方式,尽管它显然取决于你在寻找什么 foreach(var kvp in my_dictionary) { ... } 这就是你要找的吗?如果你想在C语言中使用通用词典,就像在另一种语言中使用关联数组一样: foreach(var item in myDictio

我见过几种不同的方法来用C#迭代字典。有标准的方法吗?

foreach(myDictionary中的KeyValuePair条目)
{
//对entry.Value或entry.Key执行某些操作
}

我想说,foreach是标准的方式,尽管它显然取决于你在寻找什么

foreach(var kvp in my_dictionary) {
  ...
}

这就是你要找的吗?

如果你想在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
关键字是C#3.0及以上版本的可选功能,您也可以在此处使用键/值的确切类型)

有很多选项。我个人最喜欢的是KeyValuePair

Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here

foreach (KeyValuePair<string,object> kvp in myDictionary)
{
     // Do some interesting things
}
var myDictionary = new Dictionary<string, string>(x);//fill dictionary with x

foreach(var kvp in myDictionary)//iterate over dictionary
{
    // do something with kvp.Value or kvp.Key
}
Dictionary myDictionary=newdictionary();
//在这里填充你的字典
foreach(myDictionary中的KeyValuePair kvp)
{
//做一些有趣的事情
}

您还可以使用键和值集合

这取决于您是在查找键还是在查找值

从MSDN类别说明中:

// 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);
}
//使用foreach枚举字典元素时,
//元素作为KeyValuePair对象检索。
Console.WriteLine();
foreach(openWith中的KeyValuePair kvp)
{
WriteLine(“Key={0},Value={1}”,
kvp.Key,kvp.Value);
}
//要单独获取值,请使用values属性。
Dictionary.ValueCollection valueColl=
openWith.Values;
//ValueCollection的元素是强类型的
//使用为字典值指定的类型。
Console.WriteLine();
foreach(valueColl中的字符串s)
{
WriteLine(“Value={0}”,s);
}
//要单独获取密钥,请使用keys属性。
Dictionary.KeyCollection keyColl=
openWith.key;
//KeyCollection的元素是强类型的
//具有为字典键指定的类型。
Console.WriteLine();
foreach(keyColl中的字符串s)
{
WriteLine(“Key={0}”,s);
}

如果您想在默认情况下迭代values集合,我相信您可以实现IEnumerable,其中T是dictionary中values对象的类型,“this”是dictionary

public new IEnumerator<T> GetEnumerator()
{
   return this.Values.GetEnumerator();
}
public static class DictionaryExtension
{
    public static void ForEach<T1, T2>(this Dictionary<T1, T2> dictionary, Action<T1, T2> action) {
        foreach(KeyValuePair<T1, T2> keyValue in dictionary) {
            action(keyValue.Key, keyValue.Value);
        }
    }
}
public新IEnumerator GetEnumerator()
{
返回此.Values.GetEnumerator();
}

我在MSDN上DictionaryBase类的文档中找到了此方法:

foreach (DictionaryEntry de in myDictionary)
{
     //Do some stuff with de.Value or de.Key
}

这是我唯一能够在继承自DictionaryBase的类中正确运行的类。

您在下面建议进行迭代

Dictionary<string,object> myDictionary = new Dictionary<string,object>();
//Populate your dictionary here

foreach (KeyValuePair<string,object> kvp in myDictionary) {
    //Do some interesting things;
}
Dictionary myDictionary=newdictionary();
//在这里填充你的字典
foreach(myDictionary中的KeyValuePair kvp){
//做一些有趣的事情;
}

仅供参考,
foreach
如果值为object类型,则不起作用。

在某些情况下,您可能需要for循环实现提供的计数器。为此,LINQ提供了以下功能:

for (int index = 0; index < dictionary.Count; index++) {
  var item = dictionary.ElementAt(index);
  var itemKey = item.Key;
  var itemValue = item.Value;
}
for(int index=0;index
有时,如果只需要枚举值,请使用字典的值集合:

foreach(var value in dictionary.Values)
{
    // do something with entry.Value only
}
这篇文章报道说这是最快的方法:
我很感激这个问题已经得到了很多回答,但我想做一些研究

与遍历数组之类的对象相比,遍历字典可能会非常慢。在我的测试中,数组上的迭代需要0.015003秒,而字典(元素数相同)上的迭代需要0.0365073秒,是原来的2.4倍!尽管我看到了更大的差异。为了进行比较,列表在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";
}
公共静态字符串正常(字典)
{
字符串值;
整数计数=0;
foreach(字典中的var kvp)
{
值=kvp.值;
计数++;
}
返回“正常”;
}
这一个加载键并对它们进行迭代(我也尝试将键拉入字符串[],但差别可以忽略不计)

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";
}
公共静态字符串键(字典)
{
字符串值;
整数计数=0;
foreach(dictionary.Keys中的var键)
{
值=字典[键];
计数++;
}
返回“键”;
}
在这个例子中,正常的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);
}
private静态字符串运行测试(T字典,Func函数)
{            
DateTime start=DateTime.Now;
字符串名称=null;
对于(int i=0;i<10;i++)
{
名称=函数(字典);
}
DateTime end=DateTime.Now;
var持续时间=结束。减去(开始);
返回string.Format(“{0}花费了{1}秒”,名称,持续时间.TotalSeconds);
}
在这里,正常的foreach运行花费了0.2820564秒(正如您所期望的,大约是单个迭代花费的十倍),对键的迭代花费了2.2249449秒

编辑以添加: 阅读了其他一些答案后,我不禁要问,如果我使用Dictionary而不是Dictionary,会发生什么。在本例中,数组花费了0.0120024秒,列表花费了0.0185037秒
dictionary
.AsParallel()
.ForAll(pair => 
{ 
    // Process pair.Key and pair.Value here
});
foreach (var kvp in items)
{
    // key is kvp.Key
    doStuff(kvp.Value)
}
foreach (var item in items.Values)
{
    doStuff(item)
}
foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
    // key is kvp.Key
    doStuff(kvp.Value)
}
foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
    doStuff(item)
}
foreach (DictionaryEntry entry in myDictionary)
{
     //Read entry.Key and entry.Value here
}
Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();

//Add some entries to the dictionary

myProductPrices.ToList().ForEach(kvP => 
{
    kvP.Value *= 1.15;
    Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value));
});
var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );
foreach(var item in myDictionary)
{ 
    Console.WriteLine(item.Key);
    Console.WriteLine(item.Value);
}
var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
    Console.WriteLine(fruit + ": " + number);
}
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;
    }
}
Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");

foreach (KeyValuePair<int, string> item in dict)
{
    Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
public static class IDictionaryExtensions
{
    public static IEnumerable<(TKey, TValue)> Tuples<TKey, TValue>(
        this IDictionary<TKey, TValue> dict)
    {
        foreach (KeyValuePair<TKey, TValue> kvp in dict)
            yield return (kvp.Key, kvp.Value);
    }
}
foreach (var(id, value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}
foreach ((string id, object value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}
foreach (KeyValuePair<string, object> kvp in dict)
{
    string id = kvp.Key;
    object value = kvp.Value;

    // your code using 'id' and 'value'
}
public static class DictionaryExtension
{
    public static void ForEach<T1, T2>(this Dictionary<T1, T2> dictionary, Action<T1, T2> action) {
        foreach(KeyValuePair<T1, T2> keyValue in dictionary) {
            action(keyValue.Key, keyValue.Value);
        }
    }
}
myDictionary.ForEach((x,y) => Console.WriteLine(x + " - " + y));
public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey key, out TVal value)
{
   key = pair.Key;
   value = pair.Value;
}
// Dictionary can be of any types, just using 'int' and 'string' as examples.
Dictionary<int, string> dict = new Dictionary<int, string>();

// Deconstructor gets called here.
foreach (var (key, value) in dict)
{
   Console.WriteLine($"{key} : {value}");
}
foreach(KeyValuePair<string, string> entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}
foreach(var entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}
var myDictionary = new Dictionary<string, string>(x);//fill dictionary with x

foreach(var kvp in myDictionary)//iterate over dictionary
{
    // do something with kvp.Value or kvp.Key
}
var dic = new Dictionary<int, string>() { { 1, "One" }, { 2, "Two" }, { 3, "Three" } };
foreach (var (key, value) in dic) {
    Console.WriteLine($"Item [{key}] = {value}");
}
//Or
foreach (var (_, value) in dic) {
    Console.WriteLine($"Item [NO_ID] = {value}");
}
//Or
foreach ((int key, string value) in dic) {
    Console.WriteLine($"Item [{key}] = {value}");
}
    public static void ForEach<T, U>(this Dictionary<T, U> d, Action<KeyValuePair<T, U>> a)
    {
        foreach (KeyValuePair<T, U> p in d) { a(p); }
    }

    public static void ForEach<T, U>(this Dictionary<T, U>.KeyCollection k, Action<T> a)
    {
        foreach (T t in k) { a(t); }
    }

    public static void ForEach<T, U>(this Dictionary<T, U>.ValueCollection v, Action<U> a)
    {
        foreach (U u in v) { a(u); }
    }
myDictionary.ForEach(pair => Console.Write($"key: {pair.Key}, value: {pair.Value}"));
myDictionary.Keys.ForEach(key => Console.Write(key););
myDictionary.Values.ForEach(value => Console.Write(value););
var keyList=new List<string>(dictionary.Keys);
for (int i = 0; i < keyList.Count; i++)
{
   var key= keyList[i];
   var value = dictionary[key];
 }
var dictionary = new Dictionary<int, string>();

// ...

foreach (var (key, value) in dictionary)
{
    // ...
}
SortedList<string, string> x = new SortedList<string, string>();

x.Add("key1", "value1");
x.Add("key2", "value2");
x["key3"] = "value3";
foreach( KeyValuePair<string, string> kvPair in x )
            Console.WriteLine($"{kvPair.Key}, {kvPair.Value}");