使用Linq查询丢失foreach

Mrc*_*ief 1 c# linq foreach

我想知道我是否可以用foreach某种方式用LINQ查询替换它(如果可能的话):

在线围栏:https://ideone.com/PQEytf

using System;
using System.Collections.Generic;
using System.Linq;

public class Test
{
    public static void Main()
    {
        // dummy inputs for test sake
        var keys = new[] { "key1", "key2" };

        var services = new Dictionary<string, Service>
        {
            {"key1", new Service {Components = new Dictionary<string, string> {{"comp1", "value1"}}}},
            {"key2", new Service {Components = new Dictionary<string, string> {{"comp2", "value2"}}}}
        };


        var serviceComponents = GetServiceComponents(keys, services);
        // do something with it
    }

    public static IEnumerable<ServiceComponent> GetServiceComponents(string[] keys, Dictionary<string, Service> services)
    {
        var serviceComponents = new List<ServiceComponent>();

        // this is the foreach that I want to lose
        foreach (
            var key in
                keys.Select(
                    name =>
                        services.FirstOrDefault(
                            x => x.Key.Equals(name))))
        {
            serviceComponents.AddRange(key.Value.Components.Select(component => new ServiceComponent
            {
                Name = key.Key,
                Service = component.Key,
                Value = component.Value,
            }));
        }

        return serviceComponents.ToArray();

    }
}

public class Service
{
    public Dictionary<string, string> Components { get; set; }
}

public class ServiceComponent
{
    public string Name { get; set; }
    public string Service { get; set; }
    public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 7

是的,你在寻找的是什么SelectMany.这允许您将序列中的每个项目转换为另一个序列,然后将所有这些序列展平为单个序列.(通过将所有序列放入列表中,您可以完成相同的操作,无需延迟执行.)

return keys.SelectMany(name => services.FirstOrDefault(x => x.Key.Equals(name))
    .Value.Components
    .Select(component => new ServiceComponent
    {
        Name = name.Key,
        Service = component.Key,
        Value = component.Value,
    }))
    .ToArray();
Run Code Online (Sandbox Code Playgroud)

话虽如此,这个查询正在做的是获取每个密钥,使用线性搜索在服务中查找相应的项,然后映射结果.FirstOrDefault您可以使用字典的本机功能来有效地查找每个键的值,而不是使用线性搜索:

return keys.SelectMany(key => services[key].Components
    .Select(component => new ServiceComponent
    {
        Name = key,
        Service = component.Key,
        Value = component.Value,
    }))
    .ToArray();
Run Code Online (Sandbox Code Playgroud)