Remove object from generic list by id
我有一个这样的域类:
1 2 3 4 5 | public class DomainClass { public virtual string name{get;set;} public virtual IList<Note> Notes{get;set;} } |
我该如何从
理想情况下,我希望在我的域类中有这样的方法:
1 2 3 4 5 6 7 8 9 10 11 | public virtual void RemoveNote(int id) { //remove the note from the list here List<Note> notes = (List<Note>)Notes notes.RemoveAll(delegate (Note note) { return (note.Id = id) }); } |
但我不能把
您可以筛选出不需要的项目,然后只使用所需的项目创建一个新列表:
1 2 3 4 5 6 | public virtual void RemoveNote(int id) { //remove the note from the list here Notes = Notes.Where(note => note.Id != id).ToList(); } |
edit2:此方法不需要强制转换为
1 | foreach (var n in Notes.Where(note => note.Id == id).ToArray()) Notes.Remove(n); |
或者…
1 | Notes.Remove(Notes.Where(note => note.Id == id).First()); |
第一个是最好的。第二种情况下,如果没有任何票据有
编辑:感谢马格纳斯和斯巴罗显示了我的错误。
如果您可以更改数据结构,我建议使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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); } |
}
如果id不是唯一的,则使用
您可以手动对其进行编码。原始实现是o(n*k),其中n是列表中的项数,k是要删除的项数。如果您只想删除一个项目,它会很快。
但是如果您想删除许多项,那么对于许多
旧答案中的一个可能实现:列出,不要丢失引用
这个实现的诀窍是,in将保留的项移动到o(n)中列表的开头。然后它会不断删除列表的最后一项(通常是O(1),因为不需要移动任何元素),所以截断会变成O(n)total。这意味着整个算法是O(n)。
请考虑,在某些情况下,为了更好地避免公共虚拟,请使用模板方法模式:
1 2 3 4 5 6 7 8 9 10 | 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) { } |
可以接收要删除的项数组。然后从循环中的列表中删除它们。看看这个例子:
1 2 3 4 5 6 7 8 | 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); } |