Dictionary ForAll / ForEach方法

什么是Dictionary对象的正确的ForAll方法? 我正在学习Linq类型的迭代(下面的方法1),但没有得到它的工作。 旧的foreach循环有效(下面的方法2)。 尽管在类似问题上有很多答案,例如这个问题,但我没有看到Linq迭代解决方案。

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

我做了一些GetEnumeration() ,但没有多少运气。

AsParallel()方法似乎是解决方案,在这里找到,但对我来说,我只有一个构建错误:字典不包含AsParallel的定义。

有人可能会说方法2没有太多的源代码,但对我来说,方法1的Linq迭代更简单,更直接,更优雅。

还有一种简单的方法可以使方法1工作吗?

版本:.Net Framework 4.5.2

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 ,前一段时间删除时,我不需要。 通过在我的帖子上测试几条有用的评论来发现。

现在这个问题更容易总结为:

这工作:

DictUserConfig.ToList<KeyValuePair<string, string>>().ForEach(x => Console.WriteLine(x.Key + x.Value));
DictUserConfig.AsParallel().ForAll(x => Console.WriteLine(x.Key + x.Value));

但是这不起作用:

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转换为对象(或XElement)。 所以唯一的'解决方案'似乎使用单线程创建ForEach,这已经显示为一个解决方案,但要小心返回一个XElement对象。


在测试了最终答案后,我想指出的是,讨论不是关于ForEach与foreach的相对值,而是这掩盖了Select的真实解决方案。 此外,foreach更是Fortran制造事情的方式,ForEach,特别是Select,而不是你想要达到的目标。

我想感谢大家的评论和答复,我今天学到了一些东西。


对于每个KeyValuePair<string,string>您要创建并返回具有适当属性的新XElement 。 这被称为投影

SelectLINQ的投影方法:

XDConf.Add(new XElement("settings",
    DictUserConfig.Select(
        kvp => new XElement("add", 
            new XAttribute("key", kvp.Key),
            new XAttribute("value", kvp.Value)))/*.
   Cast<object>().ToArray()*/));

最后的转换是调用XElement的正确构造函数所必需的。


请注意, List<T>.ForEach遍历枚举并为每个KeyValuePair调用一个Action<KeyValuePair<TKey,TValue>> 。 但它不会返回任何内容,因此您不能在XElement构造函数调用中使用它。


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

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

不过,我同意Sakura的评论,即正常的foreach可能是更好的选择。


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

但是你可以制作你自己的Dictionary<TKey, TVakue>方法:

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);
    }
}

然后像这样使用它:

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,那么你可以使用这样的扩展器:

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将是:

XDConf.Add(new XElement("settings",
                DictUserConfig.ForEach(x =>
                    new XElement("add", new XAttribute("key", x.Key),
                                        new XAttribute("value", x.Value))).ToArray()));

ToArray()之前可能需要Cast<object>() ToArray()

链接地址: http://www.djcxy.com/p/30405.html

上一篇: Dictionary ForAll / ForEach method

下一篇: asp.net mvc display ViewBag dictionary to javascript