在c#的for循环中修改字典

本文关键字:修改 字典 循环 for | 更新日期: 2023-09-27 18:18:20

我在C/c++方面很有经验,但在c#方面还是个新手。我的问题很简单。假设我们有一个包含整数键和值的哈希表,我们想要将哈希表中的所有值增加1。我们更喜欢用O(1)额外内存来完成这个任务。

下面是一个解决方案,在我看来,有点难看。还有别的办法能让它看起来更体面吗?

        Dictionary<int, int> dict = new Dictionary<int, int>();
        for (int i = 0; i < dict.Count; ++i)
        {
            dict[dict.Keys.ElementAt(i)]++;
        } 

PS:听说foreach在c#中是只读的。但是,有没有像c++中的for(auto it& : dict) it.second++这样的方法,我可以用它来完成c#中的任务?

在c#的for循环中修改字典

Dictionary<,>本身并没有提供这样做的好方法——因为更新与键相关的值作为一个更改计数,使任何迭代器无效。ConcurrentDictionary<,> 允许这样做,甚至有一个AddOrUpdate方法可以帮助你:

using System;
using System.Linq;
using System.Collections.Concurrent;
class Test
{
    static void Main()
    {
        var dict = new ConcurrentDictionary<int, int>
        {
            [10] = 15,
            [20] = 5,
            [30] = 10
        };
        foreach (var key in dict.Keys)
        {
            dict.AddOrUpdate(key, 0, (k, v) => v + 1);
        }
        Console.WriteLine(string.Join("'r'n", dict.Select(kp => $"{kp.Key}={kp.Value}")));
    }
}

你可以在这个实例中使用foreach,但是我们需要以一种不使用字典的方式来做,因为更新它会改变内部迭代器(这就是foreach在迭代时保持它所在位置的方式,查看这个SO了解更多细节:https://stackoverflow.com/a/398996/3874503)在这个实现中,我们将迭代键的列表,然后在迭代时更新每个键的值。

 Dictionary<int, int> dict = new Dictionary<int, int>();
 foreach (var i in dict.Keys.ToList())
 {
     dict[i]++;
 }

更新正如Servy指出的,我没有提到这个解决方案不是O(1),而是O(N)。

您不需要在循环中使用dict.Keys.ElementAt(i)索引。你可以把它当作一个数组。Dictionary在c#中相当于c++中的Map。要增加您的值所需要做的就是

for (int i = 0; i < dict.Count; i ++)
    dict[i]++;

如果您使用的是Dictionary<int, int>,则可以简单地使用

int[] dict = new int[count];

因为你的键是索引;但我真的只推荐使用List<int>。这样,您就可以动态地调整大小,而不必做所有额外的工作。

这样,你就可以像这样创建你的List<int>:
List<int> lstDict = new List<int>;
int value; /*assign to whatever value you need to insert*/
int count; /*however many elements you need*/
for (int i = 0; i < count; i ++) 
    lstDict.Add(value);
//
//  Whatever else you need to do
//
for (int i = 0; i < count; i ++)
    lstDict[i]++;
有很多方法可以让你完成你想要完成的事情。您可以使用这些选项中的任何一个来实现相同的目标。如果您想坚持使用Dictionary s,只需使用我放在那里的第一个代码片段。我个人不会使用它们,除非我需要使用两种不同的数据类型,比如Dictionary<string, int>

为什么不允许?尝试给它赋值可能不会达到您想要的效果——它不会修改原始集合的内容。这是因为变量x不是对列表中元素的引用——它是一个副本。

因为KeyValuePair对于键和值具有只读属性,因此在foreach中需要第二个字典来添加这些项并处置原始字典

        Dictionary<int, int> dict = new Dictionary<int, int>();
        dict.Add(0, 1);
        dict.Add(1, 2);
        dict.Add(2, 3);
        Dictionary<int, int> dictOutput = new Dictionary<int, int>();
        foreach (KeyValuePair<int,int> item in dict)
        {
            dictOutput.Add(item.Key, item.Value + 1);
        }
        dict.Dispose();