我正在使用包含父对象和子对象的List<T>
。在此列表中,子对象知道其相关的父对象,反之亦然。使用此列表我正在尝试实现一个业务规则,当父级属于某种类型时,最多可以从列表中删除4个子对象。换句话说,如果此类型的父级有20个孩子,则应从列表中删除其中的4个。
我在此处概述的代码将RemoveAll
符合条件的子对象。这是预期的,但我想做的是将RemoveAll
限制为只删除4个孩子。有没有办法用RemoveAll
做到这一点,还是我应该使用另一种方法?
myList.RemoveaAll(item =>
item.Child && "Foo".Equals(item.Parent.SpecialType));
答案 0 :(得分:5)
Take 扩展方法用于从IEnumerable中获取前n个匹配项。然后,您可以遍历匹配并从列表中删除它们。
var matches = myList.Where(item => item.Child && "Foo".Equals(item.Parent.SpecialType)).Take(someNumber).ToList();
matches.ForEach(m => myList.Remove(m));
答案 1 :(得分:2)
4个是否重要?如果没有,您可以使用.Take(4)
创建一个包含4个孩子的列表,然后迭代并Remove
4 ...
答案 2 :(得分:1)
试试这个:
int i = 0;
myList.Removeall(item =>
item.Child && "Foo".Equals(item.Parent.SpecialType) && i++ < 4);
请注意,我没有测试过,但它应该可以正常工作
答案 3 :(得分:0)
为什么不使用Take
功能?
答案 4 :(得分:0)
您还可以编写一个扩展方法,以构建在普通列表界面之上,如下所示:
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) ;
}
}
}