Ограничьте RemoveAll определенным количеством объектов.
Вопрос
я работаю с List<T>
который содержит как родительские, так и дочерние объекты.В этом списке дочерние объекты знают о связанном с ними родительском объекте и наоборот.Используя этот список, я пытаюсь реализовать бизнес-правило, согласно которому из списка будет удалено до 4 дочерних объектов, если их родительский объект имеет определенный тип.Другими словами, если у родителя этого типа 20 детей, 4 из них следует удалить из списка.
Код, который я изложил здесь, будет RemoveAll
дочерних объектов, соответствующих условию.Это ожидаемо, но я хотел бы ограничить RemoveAll
удалить только 4 детей.Есть ли способ сделать это с помощью RemoveAll
или есть другой метод, который мне следует использовать?
myList.RemoveaAll(item =>
item.Child && "Foo".Equals(item.Parent.SpecialType));
Решение
А Брать Метод расширения используется для получения первых n совпадений из IEnumerable.Затем вы можете перебрать совпадения и удалить их из списка.
var matches = myList.Where(item => item.Child && "Foo".Equals(item.Parent.SpecialType)).Take(someNumber).ToList();
matches.ForEach(m => myList.Remove(m));
Другие советы
Имеет ли значение, какие 4?Если нет, вы можете использовать .Take(4)
чтобы создать список из 4 дочерних элементов, затем выполнить итерацию и Remove
4...
попробуй это:
int i = 0;
myList.Removeall(item =>
item.Child && "Foo".Equals(item.Parent.SpecialType) && i++ < 4);
Обратите внимание: я не проверял, но должно работать.
Почему бы не использовать Take
функция?
Вы также можете написать метод расширения поверх обычного интерфейса списка, например:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace App
{
public static class ListExtension
{
public static int RemoveAll<T>(this List<T> list, Predicate<T> match, uint maxcount)
{
uint removed = 0;
Predicate<T> wrappingmatcher = (item) =>
{
if (match(item) && removed < maxcount)
{
removed++;
return true;
}
else
{
return false;
}
};
return list.RemoveAll(wrappingmatcher);
}
}
public interface IHero { }
public class Batman : IHero { }
public class HeroCompilation
{
public List<IHero> Herolist;
public HeroCompilation()
{
Herolist = new List<IHero>();
}
public void AddBatmans(int count){
for (int i = 1; i <= count; i++) Herolist.Add(new Batman());
}
}
class Program
{
static void ConsoleWriteBatmanCount(List<IHero> hero)
{
Console.WriteLine("There are {0} Batmans", hero.Count);
}
static void Main(string[] args)
{
HeroCompilation tester = new HeroCompilation();
ConsoleWriteBatmanCount(tester.Herolist);
tester.AddBatmans(10);
ConsoleWriteBatmanCount(tester.Herolist);
tester.Herolist.RemoveAll((x) => { return true; }, 4);
ConsoleWriteBatmanCount(tester.Herolist);
tester.Herolist.RemoveAll((x) => { return true; }, 4);
ConsoleWriteBatmanCount(tester.Herolist);
tester.Herolist.RemoveAll((x) => { return true; }, 4);
ConsoleWriteBatmanCount(tester.Herolist);
while (true) ;
}
}
}