17

I have a loop as follows:

foreach(x in myColl) 
{
    foreach(var y in x.MyList) 
    {
        result.Add(x.MyKey + y)
    }
}

That means within my inner loop I need access to a property of the current outer element.

I´m looking for a LINQ-statement but I´m unsure on it. I tried it by using

result = myColl
    .SelectMany(x => x.MyList)
    .SelectMany(x => /* how to get the key of the outer loop here */ + x)
1
  • 5
    Nested for each are easy to read, where a linq query may be more obscure. Why do you feel you need to use linq in this case? Commented Jan 29, 2016 at 13:24

3 Answers 3

21

This is easy with query expressions:

(from x in myColl
 from y in x.MyList
 select x.MyKey + y).ToList()

This works because this translates to:

myColl
.SelectMany(x => x.MyList.Select(item => new { List = x, Item = item }))
.Select(x => ...) //rest of the query, whatever you like

The key is to keep both the list as well as the list items. Channel them through the query using an anonymous type (or any other container).

Sign up to request clarification or add additional context in comments.

8 Comments

You need to name the anonymous properties.
They get their default name from the expression. This does work. Thanks for the edit.
I'm pretty sure that second SelectMany should just be a Select, or it's likely to translate to the SelectMany overload in Tormod's answer.
The names doesn't have to be stated but the first SelectMany must receive a predicate which returns an IEnumerable and it doesn't...
Honestly, I have no idea what exactly the translation results in. It does not matter for this question. And Tamir is right, the first SelectMany is completely wrong and I got 5 upvotes :)
|
5

This is when I personally prefer query syntax

var result = from x in myCol1
             from y in x.MyList
             select x.MyKey + y;

Comments

5

There is an overload of SelectMany which allows access to the "parent" element. ListOfList.SelectMany(list=>list.InnerList,(lst,element)=> HandleInnerListAndElementFromIt(lst,element))

 result = myColl.SelectMany(x => x.MyList,(x1,x2)=>DoSomething(x1,x2));

EDIT Added:

For your concrete example it looks like this:

result = myColl.SelectMany(x=>x.MyList,(x,y)=>x.MyKey+y));

Notice that there are two lambda parameters to the SelectMany method call.

First lambda will take the "x" and return a new Enumerable. x=>x.MyList

The second lambda takes the "x" and "y" and produce a new result. (x,y)=>x.MyKey+y

1 Comment

I have to admit, although it looks cool and does what I need it´s quite hard to read.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.