用LINQ语法扫描嵌套字典

本文关键字:嵌套 字典 扫描 语法 LINQ | 更新日期: 2023-09-27 18:04:51

我有这样的工作代码:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
public class Example {
    public static void Main(string[] args) {
        var files = new Dictionary<string, Dictionary<string, int>>()
                   { { "file1", new Dictionary<string, int>() { { "A", 1 } } } };
        foreach(var file in files) {
            File.WriteAllLines(file.Key + ".txt", file.Value.Select(
                    item => item.Key + item.Value.ToString("000")).ToArray());
        }
    }
}

但是我想将foreach更改为LINQ语法。

用LINQ语法扫描嵌套字典

这是你想要的吗?

var files = new Dictionary<string, Dictionary<string, int>>() 
            { { "file1", new Dictionary<string, int>() { { "A", 1 } } } };
files.ForEach(kvp =>
    File.WriteAllLines(kvp.Key + ".txt", kvp.Value.Select(
            item => item.Key + item.Value.ToString("000")).ToArray()));

根据Alexei的评论,IEnumerable.ForEach不是一个标准的扩展方法,因为它意味着变异,这不是函数式编程的目的。您可以使用如下的辅助方法添加它:

public static void ForEach<T>(
    this IEnumerable<T> source,
    Action<T> action)
{
    foreach (T element in source)
        action(element);
}    

同样,您的原始标题暗示字典的初始化语法是笨拙的。为了减少大量元素的输入/代码占用量,你可以做的是建立一个匿名对象数组,然后ToDictionary()。不幸的是,有一个小的性能影响:

var files = new [] { new { key = "file1", 
                           value = new [] { new {key = "A", value = 1 } } } }
    .ToDictionary(
        _ => _.key, 
        _ => _.value.ToDictionary(x => x.key, x => x.value));

foreach正是您应该在这里使用的。LINQ是关于查询数据的:投影、过滤、排序、分组等。您正在尝试对集合中已经存在的每个元素执行一个操作。

使用foreach进行迭代。

IEnumerable<T>上没有ForEach扩展方法是有原因的:

  • 为什么在IEnumerable接口上没有ForEach扩展方法?
  • 为什么我不使用ForEach扩展方法

主要是关于:

不使用ForEach的原因是它模糊了纯函数式代码和全状态命令式代码之间的界限。

我可以看到不使用foreach循环的唯一原因是当你想通过使用Parallel.ForEach来并行运行你的动作时:

Parallel.ForEach(
    files,
    kvp => File.WriteAllLines(kvp.Key + ".txt", kvp.Value.Select(
               item => item.Key + item.Value.ToString("000")).ToArray()));

IEnumerable<T>上使用ForEach扩展方法是一个糟糕的设计,我建议不要这样做。