【问题标题】:replace dictionary value at key using linq [duplicate]使用linq替换键处的字典值[重复]
【发布时间】:2014-07-12 21:36:08
【问题描述】:

编辑:我不觉得这是重复的——我确实没有清楚地说明我想知道一种有效的方法来将字符填充到我的字典值的左侧。我标记为答案的问题应该澄清,因为它与其他线程中的答案非常不同。对不起,我措辞错误。

我正在尝试验证我的字典中的所有值是否都具有一定的长度,如果不是,则在左侧用“0”填充它们。我知道问题是“什么”,我正在阅读字典的 KVP,然后对其进行修改,这当然会引发异常,但我不确定如何修改我的代码以使其“合法”

class prefixMe
{
    Dictionary<string, string> d = new Dictionary<string, string>();

    public prefixMe()
    {
        d.Add("one", "123456");
        d.Add("two", "678");
        d.Add("three", "13");

        foreach(KeyValuePair<string,string> k in d)
        {
            StringBuilder sb = new StringBuilder(k.Value);
            while(sb.Length != 10)
            {
                Console.WriteLine("Key:{0}\tValue:{1}", k.Key, sb);
                sb.Insert(0, '0');
            }
            d[k.Key] = sb.ToString();
            //k.Value.Replace(k.Value, sb.ToString());// = sb.ToString();
            Console.WriteLine("Key:{0}\tNew Value:{1}", k.Key, d[k.Key]);
            break;
        }

    }
}

休息;阻止代码抛出错误,但也使得它不会通过其他值,因为它打破了 foreach 循环。

结果应该是:

0000123456
0000000678
0000000013

【问题讨论】:

  • 您可以通过添加到列表的辅助函数来避免该问题:void add(string key, string val) {d.Add(key, val.PadLeft(10, '0'));}

标签: c# dictionary


【解决方案1】:

使用

foreach(KeyValuePair<string,string> k in d.ToList())

而不是

foreach(KeyValuePair<string,string> k in d)

这将创建一个键值对列表,然后您可以通过该列表进行迭代。这意味着在循环中您可以触摸字典。

如果您不介意创建新字典,那么您也可以使用 Linq 轻松替换字典。

d = d.ToDictionary(x => x.Key, x => x.Value.PadLeft(10, '0'));

【讨论】:

  • 赞成。一个线性 Linq 答案可以替换问题中 80% 的代码。
  • 这很完美——不,我对制作新字典非常满意——我只是 LINQ 的新手。我想有一种更有效的方法来做到这一点。谢谢!
  • 另外,为了它的价值,我添加了这个 where 子句来忽略空/空值被全零填充(在我的程序中,我希望它们保持空/空)d = d.Where (x => !string.IsNullOrEmpty(x.Value)).ToDictionary(x => x.Key, x => x.Value.PadLeft(10, '0'));
【解决方案2】:

使用 for 循环而不是 foreach 循环。这将允许您遍历 Dictionary 并同时对其进行修改。

编辑:在进一步谷歌搜索/尝试通过字典编译 for 循环后,您似乎实际上无法做到这一点。我找到了How to modify key in a dictionary in C#,看来您甚至无法在不删除密钥的情况下更改密钥。所以也许这个问题会对你有所帮助。

【讨论】:

  • 您能否添加一个如何迭代字典并使用for 循环更改它的示例?
  • 据我所知,您无法通过 for 循环遍历字典。
【解决方案3】:

使用PadLeft 方法,不要在第一次迭代时中断循环。

public prefixMe()
{
    d.Add("one", "123456");
    d.Add("two", "678");
    d.Add("three", "13");

    foreach(var k in d.ToList())
    {
        if(k.Value.Length != 10) 
          d[k.Key]  = k.Value.PadLeft(10, '0');
    }

}

ToList 将允许您修改您的字典。

【讨论】:

  • 如果这行得通,它也会非常有帮助,我只是转移整个字典并相应地填充。不过谢谢。
【解决方案4】:

这应该可以解决问题

Dictionary<string, string> result = d.ToDictionary(p => p.Key,p=> p.Value.PadLeft(10, '0'));

【讨论】:

  • 见@Maarten 的回答。
【解决方案5】:

使用 for 循环而不是 foreach。在 foreach 中,您无法修改集合(在您的关心中),因为您正在对其进行迭代

【讨论】:

  • 您能否添加一个如何迭代字典并使用for 循环更改它的示例?
  • 在此处查看底部答案:stackoverflow.com/questions/15241257/…
  • 这不会改变字典。
  • 并使查找每个项目成为 O(n^2) 操作。
猜你喜欢
  • 2019-11-11
  • 2019-04-15
  • 2020-04-16
  • 1970-01-01
  • 2018-09-11
  • 2021-11-18
  • 1970-01-01
  • 2022-12-03
  • 2022-01-15
相关资源
最近更新 更多