Remove object from generic list by id

前端 未结 6 1434
你的背包
你的背包 2021-02-07 10:50

I have a domain class like this:

public class DomainClass
{
  public virtual string name{get;set;}
  public virtual IList Notes{get;set;}
}


        
相关标签:
6条回答
  • 2021-02-07 11:30

    Please consider, that in some cases better to avoid public virtuals, use template method pattern in such a way:

     public void Load(IExecutionContext context) 
     { 
          // Can safely set properties, call methods, add events, etc...
          this.Load(context);            
          // Can safely set properties, call methods, add events, etc. 
     }
    
     protected virtual void Load(IExecutionContext context) 
     {
     }
    
    0 讨论(0)
  • 2021-02-07 11:36

    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();
    }
    
    0 讨论(0)
  • 2021-02-07 11:39

    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.

    0 讨论(0)
  • 2021-02-07 11:43

    You can receive an array of items for removing. Than remove them from list in loop. Look at this sample:

    IList<int> list = new List<int> { 1, 2, 3, 4, 5, 1, 3, 5 };
    
    var valuesToRemove = list.Where(i => i == 1).ToArray();
    
    foreach (var item in valuesToRemove)
    {
        list.Remove(item);
    }
    
    0 讨论(0)
  • 2021-02-07 11:49

    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.

    0 讨论(0)
  • 2021-02-07 11:54

    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).

    0 讨论(0)
提交回复
热议问题