Remove object from generic list by id

Edit2: This method doesn't require casting to a List!

foreach (var n in Notes.Where(note => note.Id == id).ToArray()) Notes.Remove(n);

or...

Notes.Remove(Notes.Where(note => note.Id == id).First());

The first one is the best.
The second one will throw an exception if no notes have that id.

Edit: Thanks to Magnus and rsbarro for showing my mistake.


You could filter out the items you don't want and create a new list with only the items you do want:

public virtual void RemoveNote(int id)
{
   //remove the note from the list here

   Notes = Notes.Where(note => note.Id != id).ToList();
}

If you can change the datastructure I would suggest using a Dictionary. Than you can go with:

public class DomainClass
{
  public virtual string name{get;set;}
  public virtual IDictionary<int, Note> Notes {get; set;}

  //Helper property to get the notes in the dictionary
  public IEnumerable<Note> AllNotes
  {
    get
    {
      return notes.Select (n => n.Value);
    }
  }

  public virtual void RemoveNote(int id)
  {
     Notes.Remove(id);
  }

}

If ID is not unique use IDictionary<int, IList<Note>> instead.


You can either code it manually. The naive implementation is O(n*k) with n the number of items in the list, and k the number of items you want to remove. If you want to just remove a single item it is fast.

But if you want to remove many items then the native implementation becomes O(n^2) for many IList<T> implementations(including List<T>, no idea how NHibernate's list behaves) and you need to write a bit more code to get a O(n) RemoveAll implementation.

One possible implementation from an old answer: List, not lose the reference

The trick with this implementation is that in moves the kept items to the beginning of the list in O(n). Then it keeps removing the last item of the list(which is usually O(1) since no elements need to move), so the truncation becomes O(n) total. This means the whole algorithm is O(n).