Limit RemoveAll auf eine bestimmte Anzahl von Objekten
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));
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) ;
}
}
}