Ограничьте RemoveAll определенным количеством объектов.

StackOverflow https://stackoverflow.com/questions/1890178

  •  19-09-2019
  •  | 
  •  

Вопрос

я работаю с 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) ;
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top