首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字典ForAll / ForEach方法

字典ForAll / ForEach方法
EN

Stack Overflow用户
提问于 2016-02-22 15:06:18
回答 2查看 4.8K关注 0票数 2

对于ForAll对象,正确的Dictionary方法是什么?我正在学习Linq类型的迭代(下面的方法1),但是不能让它工作。旧的foreach循环可以工作(下面是方法2)。尽管在类似的问题上有许多答案,例如this question,但我没有看到Linq迭代的解决方案。

字典似乎有获取所有键或所有值的方法,可以在Linq迭代中使用,但不能获得所有的KeyValuePairs。奇怪!

我对GetEnumeration()做了一些摆弄,但运气不佳。

AsParallel()方法似乎是解决方案,找到了here,但我只得到了一个构建错误:字典不包含AsParallel的定义。

可以说,方法2没有那么多行源,但对我来说,方法1的Linq迭代仍然更简单、更直接、更优雅。

还有一个简单的方法让方法1起作用吗?

版本:.Net框架4.5.2

代码语言:javascript
复制
using System.Linq;//AsParallel, ToList
using System.Collections.Generic;//Dictionary
using System.Xml.Linq;//XElement
using System.IO;//Path, Dir, File

        public Dictionary<string, string> DictUserConfig = new Dictionary<string, string>();

        public void SaveFile(string FileName)
        {
            XDocument XDConf = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
#if true//method 1: problem: Dictionary does not have a .ForAll or .ForEach method, or .GetEnumerator().ForAll(x => ...)
            XDConf.Add(
                new XElement("settings",
                    DictUserConfig.ForEach(x =>
                        new XElement("add",
                            new XAttribute("key", x.Key),
                            new XAttribute("value", x.Value)))));
#else//method 2: works
            XElement XSettings = new XElement("settings");
            XDConf.Add(XSettings);
            foreach (KeyValuePair<string, string> x in DictUserConfig)
            {
                XSettings.Add(
                    new XElement("add",
                        new XAttribute("key", x.Key),
                        new XAttribute("value", x.Value)));
            }
#endif
            XDConf.Save(FileName);
            return;
        }

更新:我发现了一个问题:丢失了using System.Linq,这是一段时间前我不需要的时候删除的。通过测试我的帖子中的几个有用的评论发现。

现在更容易将问题概括为:

这样做是可行的:

代码语言:javascript
复制
DictUserConfig.ToList<KeyValuePair<string, string>>().ForEach(x => Console.WriteLine(x.Key + x.Value));
DictUserConfig.AsParallel().ForAll(x => Console.WriteLine(x.Key + x.Value));

但这是行不通的:

代码语言:javascript
复制
XElement XE1 =  (XElement)DictUserConfig.ToList<KeyValuePair<string, string>>().ForEach(x => new XElement(x.Key, x.Value));
XElement XE2 =  DictUserConfig.AsParallel().ForEach(x => new XElement(x.Key, x.Value));

原因是,我想,ToList和AsParallel不会将ForEach的结果返回给this。生成错误是:无法将void转换为object (或XElement)。因此,唯一的“解决方案”似乎是自己使用一行程序创建ForEach,它已经显示为解决方案,但要注意返回一个XElement对象。

在测试了最后的答案之后,我想指出的是,讨论并不是关于foreach相对于ForEach的相对值,而是讨论了选择的真正解决方案。而且,foreach更多的是使某些事情发生的Fortran方式,以及ForEach,特别是Select,而不是关于您想要实现的目标。

我要感谢大家的评论和回答,我今天从中学到了一些东西。

EN

回答 2

Stack Overflow用户

发布于 2016-02-22 15:19:43

您可以使用ToList扩展方法来获得与ForEach方法兼容的KeyValuePairs列表。

代码语言:javascript
复制
Dictionary<string, int> testDict = new Dictionary<string, int>();
testDict.Add("one", 1);
testDict.Add("two", 2);
testDict.Add("three", 3);

testDict.ToList<KeyValuePair<string, int>>().ForEach(x => Console.WriteLine(x.Key));

DotNetFiddle这里:https://dotnetfiddle.net/5rRGZc

不过,我同意樱花的说法,即正常的预见可能是更好的选择。

票数 2
EN

Stack Overflow用户

发布于 2016-02-22 15:14:43

ForEach()List<T>类的一种特殊方法。

但是您可以创建自己的Dictionary<TKey, TVakue>扩展程序方法。

代码语言:javascript
复制
public static class DictionaryExtensions
{
    public static void ForEach<TKey, TValue>(this Dictionary<TKey, TValue> dict, Action<KeyValuePair<TKey, TValue>> action)
    {
        foreach (var item in dict)
            action(item);
    }
}

然后像这样使用它:

代码语言:javascript
复制
XElement XSettings = new XElement("settings");
DictUserConfig.ForEach(x =>
    XSettings.Add(new XElement("add",
            new XAttribute("key", (string)x.Key),
            new XAttribute("value", (string)x.Value))));

更新

使用方法1,则可以使用如下所示的扩展器:

代码语言:javascript
复制
public static IEnumerable<TResult> ForEach<TKey, TValue, TResult>(this Dictionary<TKey, TValue> dict, Func<KeyValuePair<TKey, TValue>, TResult> func)
{
    foreach (var item in dict)
        yield return func(item);
}

那么方法1将是:

代码语言:javascript
复制
XDConf.Add(new XElement("settings",
                DictUserConfig.ForEach(x =>
                    new XElement("add", new XAttribute("key", x.Key),
                                        new XAttribute("value", x.Value))).ToArray()));

可能Cast<object>()ToArray()之前是必需的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35556999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档