将RemoveAll限制为一定数量的对象

时间:2009-12-11 19:00:48

标签: c# lambda removeall

我正在使用包含父对象和子对象的List<T>。在此列表中,子对象知道其相关的父对象,反之亦然。使用此列表我正在尝试实现一个业务规则,当父级属于某种类型时,最多可以从列表中删除4个子对象。换句话说,如果此类型的父级有20个孩子,则应从列表中删除其中的4个。

我在此处概述的代码将RemoveAll符合条件的子对象。这是预期的,但我想做的是将RemoveAll限制为只删除4个孩子。有没有办法用RemoveAll做到这一点,还是我应该使用另一种方法?

myList.RemoveaAll(item =>
  item.Child && "Foo".Equals(item.Parent.SpecialType));

5 个答案:

答案 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) ;
        }
    }
}