nemo_87
nemo_87

Reputation: 4781

Reduce multiple foreach loops in code C#

I have wrote a really messy code, just because I did not had an idea how to loop through the multiple list of objects.

Code is working what it suppose to do, but I am not confident with it. Does someone has an idea how this kind of code can be refactored so it is more readable?

foreach (var outlet in merchant.Outlets)
{
    if (outlet != null)
    {
        foreach (var terminal in merchant.Terminals)
        {
            if (terminal != null)
            {
                foreach (var agreement in terminal.AssociateAgreements)
                {
                    var bankInfo = new Bank();
                    if (agreement != null)
                    {
                        bankInfo.UniqueID = AgreementUniqueCode + agreement.ID;
                        bankInfo.BankBIC = agreement.BankAccountInformation.SwiftBIC;
                        bankInfo.BankName = agreement.BankAccountInformation.BankName;
                        bankInfo.Address =
                            AddressEntityToAddress(agreement.BankAccountInformation.BankAddress,
                                BankingType);

                        bankInfo.type = BankType;
                    }
                    banksAccountInformation.Add(bankInfo);
                }
            }
        }
    }
} 

Upvotes: 1

Views: 6169

Answers (4)

wonsik Lee
wonsik Lee

Reputation: 1

if i am:

foreach (var outlet in merchant.Outlets)
{
    if (outlet == null)
        continue;

    foreach (var terminal in merchant.Terminals)
    {
        if (terminal == null)
            continue;

        foreach (var agreement in terminal.AssociateAgreements)
        {
            if (agreement == null)
                continue;

            //TODO
        }
    }
}

Upvotes: 0

JanDotNet
JanDotNet

Reputation: 4016

You could also use the linq query syntax:

var outletQuery = from outlet in merchant.Outlets
                  where outlet != null
                  select outlet;

var agreementQuery = from terminal in merchant.Terminals
                     where terminal != null
                     from agreement in terminal.AssociateAgreements
                     select agreement;

foreach (var outlet in outletQuery)
{
    foreach (var agreement in agreementQuery)
    {
       ProcessAgreement(agreement);
    }
}

Upvotes: 3

Pavel Voronin
Pavel Voronin

Reputation: 13985

If the only thing you want to is drilling down the object hierarchy, then you can use extension methods or linq:

// here you get a flattened collection of Terminals
merchants.SelectMany( m => m.Terminals)
// here you get a flattened collection of all AssociateAgreements of all Terminals
   .SelectMany( t => t.AssociateAgreements)

Upvotes: 3

Tim Schmelter
Tim Schmelter

Reputation: 460058

You could use LINQ, especially SelectMany and Where:

List<Bank> banksAccountInformation = merchant
    .Where(m => m.Outlets != null && m.Terminals != null)
    .SelectMany(m => m.Terminals
        .SelectMany(t => t.AssociateAgreements
            .Where(aa => aa != null)
            .Select(aa => new Bank
            {
                UniqueID = AgreementUniqueCode + aa.ID
                // ...
            })))
    .ToList();

Upvotes: 4

Related Questions