0

I'm trying to learn linq, but struggling with some concepts. How would I transform this double foreach loop into a linq query please?

foreach (var l1 in list1)
{
    foreach (var l2 in list2)
    {
       if (l1 == l2)
       {
          list1.Remove(l1);
       }
    }
}
3
  • 4
    You wouldn't, because LINQ is about querying, not acting. Queries do not (should not) modify sequences. At best, you'd write a query that identifies the elements to be removed; then remove them in a second, separate step. Or derive a new sequence (with only a subset of the original elements) from the original sequences. Commented Feb 6, 2015 at 15:07
  • 1
    You shouldn't be mutating a list you are iterating over in the first place. Commented Feb 6, 2015 at 15:12
  • By the way: Note that your title is inaccurate. You do not have a list within a list; that would only be the case if you had a List<List<T>>. What you do have is a loop within a loop (both acting on a list and a list). Commented Feb 8, 2015 at 17:00

4 Answers 4

7
var list3 = list1.Except(list2);

LINQ does not mutate lists.

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

3 Comments

As long as nothing else holds a reference to list1 and expects it to be updated...
I'm always amazed how simply some tasks can be done if only you know how. Anyway I'm getting there slowly. thanks!
@user3611219 If you spent some time looking through what all of the LINQ operators are and what each of them do (when trying to learn LINQ) you wouldn't be so surprised when one of them does exactly what you're trying to do. That should be step 1 of learning LINQ.
3

If list1 is declared as a List<T>, then you can do this:

list1.RemoveAll(list2.Contains);

You might find that a little difficult to read. The above is essentially equivalent to:

list1.RemoveAll(item1 => list2.Contains(item1));

Note that this solution is not based on LINQ. However, if list2's type does not have a Contains method, then LINQ can help you out with its .Contains extension method; add a using System.Linq; directive to your code in that case.)

P.S.: Please make sure that you have read and understood my above comment: LINQ's purpose is querying for data, not modifying it.

Comments

0

There is number of ways to do it, one example is to use Intersect:

var inBothLists = list1.Intersect(list2);

inBothLists.ToList().ForEach(i => list1.Remove(i));

Comments

0

Linq is for querying, not updating, but you could query for the items that need to be removed and then remove them in a loop:

var itemsToRemove = list1.Where(l2.Contains(l1));
foreach(var item in itemsToRemove)
{
    list1.Remove(item)
}

Comments

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.