Search code examples
c#linq

Converting inner loops to LINQ


How can I re-write this nicer with LINQ?

var result = new MostOuterClass();

foreach (var item in data.Item1)
{
    var workflows = data.Item2.Where(t => t.WorkFlowName == item.Name);
    MainClass twf = new();

    foreach (var w in workflows)
    {
        TabOneClass wf = new()
        {
            Permissions = data.Item4.Where(p => p.StatusName == w.StatusName).Select(t => new LowestLeafClass()
            {
                ShortName = t.ShortName,
                StatusName = t.StatusName,
                TransitionName = t.TransitionName,

            }),
            TransitionName = w.TransitionName,
            WorkFlowName   = w.WorkFlowName,
        };
        twf.TabOneItems.Add(wf);
    }
    result.MainClassItems.Add(twf);
}

Here is also the used classes so you can see how the data is shaped:

public class MostOuterClass
{
    public List<MainClass> MainClassItems { get; set; } = new List<MainClass>();
}

public class MainClass
{
    public List<TabOneClass>  TabOneItems { get; set; } = new List<TabOneClass>();  
    public int                Id          { get; set; }
    public string             Name        { get; set; } = string.Empty;        
}

public class TabOneClass
{
    public IEnumerable<LowestLeafClass>    Permissions     { get; set; } = Enumerable.Empty<LowestLeafClass>();
    public string                          WorkFlowName    { get; set; } = string.Empty;
    public string                          StatusName      { get; set; } = string.Empty;    
    public string                          TransitionName  { get; set; } = string.Empty;
    public string                          Status          { get; set; } = string.Empty;        
}

public class LowestLeafClass
{
    public string ShortName            { get; set; } = string.Empty;
    public string StatusName           { get; set; } = string.Empty;
    public string TransitionName       { get; set; } = string.Empty;
}

Solution

  • It's all about Select and ToList. In the end, it's not better and especially not really of greater readability to write it down in a LINQ statement as compared to nested foreach. It's just a few keywords less ... (Except that using ToList() is more effective than multiple list.Add())

    var result = new MostOuterClass {
            MainClassItems = data.Item1.Select(item =>
                new MainClass {
                    TabOneItems = data.Item2
                        .Where(t => t.WorkFlowName == item.Name)
                        .Select(w =>
                            new TabOneClass {
                                TransitionName = w.TransitionName,
                                WorkFlowName = w.WorkFlowName,
                                Permissions = data.Item4
                                  .Where(p => p.StatusName == w.StatusName)
                                  .Select(t => 
                                      new LowestLeafClass {
                                          ShortName = t.ShortName,
                                          StatusName = t.StatusName,
                                          TransitionName = t.TransitionName
                                      })}
                        ).ToList()
                }).ToList()
        };