Everyone , I tried to remove item based on condition but it seems that after executing the remove statement my list stays the same .
class Menu
public class Menu : Entity
{
/// <summary>
/// Tạo mới guid khi gọi tới menu
/// </summary>
public Menu()
{
Random rnd = new Random();
Id = rnd.Next(1,999999) * DateTime.Now.Millisecond;
Guid = Guid.NewGuid();
}
/// <summary>
/// Danh sách Role
/// </summary>
[Required(ErrorMessage = nameof(EnumManageMenu.ENM01))]
public ICollection<string> Roles { get; set; }
/// <summary>
/// Danh sách Permisions
/// </summary>
[Required(ErrorMessage = nameof(EnumManageMenu.ENM02))]
public ICollection<string> Permisions { get; set; }
/// <summary>
/// Tên của từng menu
/// </summary>
[Required(ErrorMessage = nameof(EnumManageMenu.ENM03))]
[MaxLength(200, ErrorMessage = nameof(EnumManageMenu.ENM07))]
public string Name { get; set; }
/// <summary>
/// Đường dẫn
/// </summary>
[Required(ErrorMessage = nameof(EnumManageMenu.ENM09))]
[MaxLength(1000, ErrorMessage = nameof(EnumManageMenu.ENM08))]
public string Link { get; set; }
/// <summary>
/// Mỗi menu sẽ chứa một loại menu
/// </summary>
public ICollection<Menu> Items { get; set; }
/// <summary>
/// Mô tả thêm của từng menu
/// </summary>
[MaxLength(2000, ErrorMessage = nameof(EnumManageMenu.ENM11))]
public string Description { get; set; }
/// <summary>
/// Loại menu
/// </summary>
[Required(ErrorMessage = nameof(EnumManageMenu.ENM03))]
[MaxLength(1000, ErrorMessage = nameof(EnumManageMenu.ENM013))]
public string EnumCode { get; set; }
/// <summary>
/// Icon của menu
/// </summary>
[Required(ErrorMessage = nameof(EnumManageMenu.ENM016))]
[MaxLength(1000, ErrorMessage = nameof(EnumManageMenu.ENM017))]
public string Icon { get; set; }
/// <summary>
/// Trạng thái của menu
/// </summary>
public bool Active { get; set; }
/// <summary>
/// Sắp xếp danh sách menu
/// </summary>
public int SortOrder { get; set; }
}
below is my code
public async Task<MethodResult<List<MenuModel>>> GetAllMenuAsync()
{
MethodResult<List<MenuModel>> methodResult = new MethodResult<List<MenuModel>>();
List<Menu> empty = new List<Menu>();
List<Menu> menus = await _dbCollection.Find(FilterDefinition<Menu>.Empty).ToListAsync();
empty = menus;
int countList = menus.Count;
for (int i = 0; i < countList; i )
{
foreach (var item in GetListNoDel(menus[i]))
{
if (item.IsDeleted)
{
empty.Remove(item);
}
}
}
List<MenuModel> menuModels = _mapper.Map<List<MenuModel>>(empty);
methodResult.Result = menuModels;
return methodResult;
}
private IEnumerable<Menu> GetListNoDel(Menu menus)
{
yield return menus;
foreach (var item in menus.Items)
{
foreach (var items in GetListNoDel(item))
{
yield return items;
}
}
}
CodePudding user response:
You cannot "foreach" over a list and immediately remove items (as you undoubtedly know). So you will have to first find the items to remove, and then remove them. A twist in your case is that those "items to remove" can be at any depth in a menu tree.
So when you find an item to remove, also remember which list it appears in. Then you can directly remove it from that list.
void MainMethod()
{
var menulist = new List<Menu>(); // omitted: fill list
// get the *full* list of items to remove,
// so you don't change a list that is still used in a foreach
var todelete = ToDelete(menulist).ToList();
// and remove them from their parent list
foreach (var todo in todelete)
{
todo.list.Remove(todo.child);
}
}
private IEnumerable<(List<Menu> list, Menu child)> ToDelete(List<Menu> menuitems)
{
foreach (var item in menuitems)
{
if (item.IsDeleted)
{
// now we know that "item" must be removed from "menuitems"
yield return (menuitems, item);
}
else
{
// if the parent is deleted, then all children will be gone as well
// - so only recursively check non-deleted items
// pass the results of a recursive call up the call stack
foreach (var pairs in ToDelete(item.Items))
{
yield return pairs;
}
}
}
}