0

Hi i am new to linq kindly pardon my bad keywords.

 IList<Log> pendingLogs = rep.GetAllPending();
 IList<Short> pendingMessageInQueue = PendingCommandModel.GetPendingMessagesIds();

I have two lists. I want to remove items from pendingLogs where item.Id exists in pendingMessageInQueue. I could also have used IEnumerable if that is more appropriate in this case.

Shevliaskovic
  • 1,562
  • 4
  • 26
  • 43
Shanker Paudel
  • 740
  • 1
  • 9
  • 21

2 Answers2

1

If you want to keep your original list instead of creating a new one, you can use a simple join to get the items you want to delete:

 foreach(var log in pendingMessageInQueue.Join(pendingLogs, 
                                               (id) => id,
                                               (log) => log.Id,
                                               (id, log) => log))
{
    pendingLogs.Remove(log);
}
Community
  • 1
  • 1
sloth
  • 99,095
  • 21
  • 171
  • 219
  • 1
    Are you sure that this works? You're removing items from the list in a `foreach` which should raise an "Collection was modified; enumeration operation may not execute"-exception. – Tim Schmelter May 22 '14 at 07:45
  • 1
    @TimSchmelter Yes, I'm sure. It works because `pendingLogs` is the *inner* part of the join, which will be converted into a `LookUp<,>` inside the `Join` method. Thus `pendingLogs` itself will be enumerated while `Remove` is called. But it would fail when `pendingLogs` where the *outer* part of the join. – sloth May 22 '14 at 07:58
  • You're right. However, i find it difficult to remember whether it is allowed or not. That's why i prefer a different approach in this case, although the `Join` can be more efficient.. – Tim Schmelter May 22 '14 at 08:04
  • Well, both ways have pros and cons. – sloth May 22 '14 at 08:45
0

Create a new list with all items that you want to keep, you can use !Contains:

pendingLogs = pendingLogs 
    .Where(pl => !pendingMessageInQueue.Contains(pl.id))
    .ToList();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Can you suggest me when to use Ilist or IEnumerable ?? – Shanker Paudel May 22 '14 at 07:35
  • 1
    @ShankerPaudel: `IEnumerable` is the interface `List` is an implementation. Use the appropriate type, if you want that the user of the collection cannot modify it easily make it `IEnumerable` since it doesn't support `Add` or `Remove` methods. If you want that the collection can be (or must be) changed afterwards use a `List`. I tend to use `IEnumerable` to encapsulate it if the collection is filled completely. **Edit** Read this: http://stackoverflow.com/questions/3628425/ienumerable-vs-list-what-to-use-how-do-they-work (LINQ only answers) – Tim Schmelter May 22 '14 at 07:37
  • Also, if you want that the user of the collection cannot modify it, you can use the `AsReadOnly()` method of the `List<>` class so the `IEnumerable` can't be cast back to `List<>` and be modified. – sloth May 22 '14 at 07:43