I was wondering if I could replace this foreach
with LINQ queries somehow (if possible):
Online playpen: 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; }
}
What you need is
SelectMany
, however, by usingFirstOrDefault
you're opening yourself up to aNullReferenceException
(as the default value for any reference type isnull
). If you intend to have aNullReferenceException
thrown when an element ofkeys
is not a key inservices
then you can use other answers which leverageSelectMany
. However, is you do not intend aNullReferenceException
, then you should use something like the following:This statement removes all key-value pairs from
services
whose key is not in thekeys
array, then turns each element of each pair'sComponents
into a newServiceComponent
object, with theSelectMany
making a single flat list out of the newServiceComponent
s.