user3086989
user3086989

Reputation: 75

LINQ expression instead of nested foreach loops

I have these two clases:

public class Client{
    public List<Address> addressList{get;set;}
} 

public class Address{
    public string name { get; set; }
}

and I have a List of type Client called testList. It contains n clients and each one of those contains n addresses

List<Client> testList;

how can i do the following using LINQ:

foreach (var element in testList)
{
    foreach (var add in element.addressList)
    {
        console.writeLine(add.name);
    }
} 

Upvotes: 2

Views: 2972

Answers (7)

Tim S.
Tim S.

Reputation: 56536

LINQ doesn't include a ForEach function, and they don't intend to, since it goes against the idea of LINQ being functional methods. So you can't do this in a single statement. List<T> has a ForEach method, but I'd recommend not using this for the same reasons that it's not in LINQ.

You can, however, use LINQ to simplify your code, e.g.

foreach (var add in testList.SelectMany(x => x.addressList))
{
    Console.WriteLine(add.name);
}
// or
foreach (var name in testList.SelectMany(x => x.addressList).Select(x => x.name))
{
    Console.WriteLine(name);
}

Upvotes: 1

theyetiman
theyetiman

Reputation: 8888

foreach(var add in testList.SelectMany(element => element.addressList)){
    Console.WriteLine(add.name);
}

Upvotes: 2

Hossein Narimani Rad
Hossein Narimani Rad

Reputation: 32481

This may helps:

testList.ForEach(i => i.addressList.ForEach(j => Console.WriteLine(j.name)));

Upvotes: 2

Alberto
Alberto

Reputation: 15941

Use the ForEach method:

testList.ForEach(tl=>tl.addressList.ForEach(al=>console.writeLine(al.name)));

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499950

Well I wouldn't put the Console.WriteLine in a lambda expression, but you can use SelectMany to avoid the nesting:

foreach (var add in testList.SelectMany(x => x.addressList))
{
    Console.WriteLine(add.name);
}

I see little reason to convert the results to a list and then use List<T>.ForEach when there's a perfectly good foreach loop as part of the language. It's not like you naturally have a delegate to apply to each name, e.g. as a method parameter - you're always just writing to the console. See Eric Lippert's blog post on the topic for more thoughts.

(I'd also strongly recommend that you start following .NET naming conventions, but that's a different matter.)

Upvotes: 8

MarcinJuraszek
MarcinJuraszek

Reputation: 125620

foreach(var a in testList.SelectMany(c => c.addressList))
{
    Console.WriteLine(a.name);
}

It will not materialize any new collection.

Upvotes: 2

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236208

testList.SelectMany(c => c.addressList)
        .Select(a => a.name)
        .ToList()
        .ForEach(Console.WriteLine)

Upvotes: 1

Related Questions