Frage

ich mit einem List<T> arbeite, die beide Eltern und Kinder Objekte enthält. In dieser Liste sind Kinder Objekte ihrer zugehörigen übergeordneten Objekt und umgekehrt bewusst. Mit dieser Liste Ich versuche, eine Geschäftsregel zu implementieren, wo bis zu 4 Kinder Objekte aus der Liste entfernt werden, wenn ihre Eltern eines bestimmten Typs ist. Anders ausgedrückt, wenn ein Elternteil dieser Art hat 20 Kinder 4 von ihnen sollte aus der Liste entfernt werden.

Der Code, den ich hier skizziert habe, wird von den Kindern Objekten RemoveAll, die die Bedingung erfüllen. Dies ist zu erwarten, aber was ich mag ist zu tun, um die RemoveAll zu begrenzen nur 4 Kinder zu entfernen. Gibt es ein Mittel, dies zu tun mit RemoveAll oder gibt es eine andere Methode, die ich verwenden soll?

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

Lösung

Nehmen Erweiterungsmethode verwendet wird, um die ersten n Anzahl von Übereinstimmungen von einem IEnumerable zu greifen. Anschließend können Sie durch die Spiele durchlaufen und sie aus der Liste entfernen.

var matches = myList.Where(item => item.Child && "Foo".Equals(item.Parent.SpecialType)).Take(someNumber).ToList();
matches.ForEach(m => myList.Remove(m));

Andere Tipps

Ist es egal, welche 4? Wenn nicht, können Sie .Take(4) verwenden, um eine Liste von 4 Kindern zu schaffen, dann durchlaufen und Remove 4 ...

versuchen Sie dies:

int i = 0;
myList.Removeall(item =>
  item.Child && "Foo".Equals(item.Parent.SpecialType) && i++ < 4);

Beachten Sie, dass ich es nicht getestet, aber es sollte funktionieren

Warum verwenden Sie die Take Funktion nicht?

Sie können auch eine Erweiterungsmethode bauen auf dem normalen Listen Schnittstelle wie folgt schreiben

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) ;
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top