Wie entferne ich ein Element aus der Liste in C #?

189

Ich habe eine Liste in der Ergebnisliste wie folgt gespeichert:

var resultlist = results.ToList();

Es sieht ungefähr so ​​aus:

ID FirstName  LastName
-- ---------  --------
1  Bill       Smith
2  John       Wilson
3  Doug       Berg

Wie entferne ich ID 2 aus der Liste?

Nate Pet
quelle

Antworten:

364

List<T> hat zwei Methoden, die Sie verwenden können.

RemoveAt (int index) kann verwendet werden, wenn Sie den Index des Elements kennen. Beispielsweise:

resultlist.RemoveAt(1);

Oder Sie können Entfernen (T-Element) verwenden :

var itemToRemove = resultlist.Single(r => r.Id == 2);
resultList.Remove(itemToRemove);

Wenn Sie nicht sicher sind, ob das Element wirklich vorhanden ist, können Sie SingleOrDefault verwenden . SingleOrDefaultwird zurückgegeben, nullwenn kein Element vorhanden ist ( Singlelöst eine Ausnahme aus, wenn das Element nicht gefunden werden kann). Beide werfen, wenn es einen doppelten Wert gibt (zwei Elemente mit demselben id).

var itemToRemove = resultlist.SingleOrDefault(r => r.Id == 2);
if (itemToRemove != null)
    resultList.Remove(itemToRemove);
Wouter de Kort
quelle
5
gut, als vielleichtvar itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove);
Vlad
1
Sollte das nicht sein resultlist.Items.RemoveAt(1);?
DreamTeK
48

Kurze Antwort:
Entfernen (aus der Liste results)

results.RemoveAll(r => r.ID == 2);entfernt den Artikel mit der ID 2 in results(an Ort und Stelle).

Filter (ohne aus der ursprünglichen Liste zu entfernen results):

var filtered = result.Where(f => f.ID != 2);Gibt alle Elemente außer dem mit der ID 2 zurück

Detaillierte Antwort:

Ich denke, es .RemoveAll()ist sehr flexibel, da Sie eine Liste von Artikel-IDs haben können, die Sie entfernen möchten - beachten Sie bitte das folgende Beispiel.

Wenn Sie haben:

class myClass {
    public int ID; public string FirstName; public string LastName;
}

und wies einige Werte resultswie folgt zu:

var results=new List<myClass> {
    new myClass()  { ID=1, FirstName="Bill", LastName="Smith" },
    new myClass()  { ID=2, FirstName="John", LastName="Wilson" },
    new myClass()  { ID=3, FirstName="Doug", LastName="Berg" },
    new myClass()  { ID=4, FirstName="Bill", LastName="Wilson" },
};

Anschließend können Sie eine Liste der zu entfernenden IDs definieren:

var removeList = new List<int>() { 2, 3 };

Und verwenden Sie dies einfach, um sie zu entfernen:

results.RemoveAll(r => removeList.Any(a => a==r.ID));

Es werden die Elemente 2 und 3 entfernt und die Elemente 1 und 4 beibehalten - wie in der Tabelle angegeben removeList. Beachten Sie, dass dies an Ort und Stelle geschieht, sodass keine zusätzliche Zuordnung erforderlich ist.

Natürlich können Sie es auch für einzelne Elemente verwenden, z.

results.RemoveAll(r => r.ID==4);

In unserem Beispiel wird Bill mit der ID 4 entfernt.


DotNetFiddle: Führen Sie die Demo aus

Matt
quelle
45
resultList = results.Where(x=>x.Id != 2).ToList();

Ich mag einen kleinen Linq-Helfer, der einfach zu implementieren ist und Abfragen mit "wo nicht" -Bedingungen etwas einfacher zu lesen macht:

public static IEnumerable<T> ExceptWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
{
    return source.Where(x=>!predicate(x));
}

//usage in above situation
resultList = results.ExceptWhere(x=>x.Id == 2).ToList();
KeithS
quelle
1
Ein anderer ähnlicher Ansatz (der ein Prädikat verwendet) ist die Verwendung von List.FindIndex/ List.RemoteAt(das die Funktion "nett" oder "nicht so nett" hat, eine mutierende Operation zu sein).
Das stimmt, aber vorsichtig sein , zu sagen , dass List Betrieb ist mutiert. List verwendet ein Array hinter den Kulissen und kann sein Array mit einer kleineren oder größeren Kapazität neu erstellen, wenn es dies für erforderlich hält. Normalerweise ist das Entfernen eine In-Place-Mutation des vorhandenen Arrays.
KeithS
Dies ist nicht threadsicher, und für seine Einfachheit können Sie nur SingleOrDefault verwenden, es muss nicht in einer statischen Methode enthalten sein
Niemand sagte, es sei threadsicher (und ob dies davon abhängt, was die Threads tun sollen; es kann tatsächlich vorzuziehen sein, einem Arbeitsthread ein anderes In-Memory-Konstrukt zuzuweisen, als sie alle an einer gleichzeitigen Sammlung arbeiten zu lassen ), und das OP möchte alle Datensätze außer dem, der dem Prädikat entspricht, sodass SingleOrDefault tatsächlich genau das zurückgibt, was sie nicht möchten. Die "statische Methode" ist in der Tat eine Erweiterungsmethode, wie die meisten von Linq, und funktioniert immer dann, wenn das, was Sie nicht wollen (ein oder mehrere Elemente), einfacher zu definieren ist als das, was Sie tun.
KeithS
5

Es gibt einen anderen Ansatz. Es verwendetList.FindIndex und List.RemoveAt.

Während ich wahrscheinlich die von KeithS vorgestellte Lösung verwenden würde (nur das einfache Where/ ToList), unterscheidet sich dieser Ansatz darin das ursprüngliche mutiert . Dies kann je nach Erwartungen eine gute (oder eine schlechte) "Eigenschaft" sein.

In jedem Fall stellt das FindIndex(in Verbindung mit einem Schutz) sicher RemoveAt, dass das korrekt ist, wenn es Lücken in den IDs gibt oder die Reihenfolge falsch ist usw. und die Verwendung von RemoveAt(vs Remove) a vermeidet zweite O (n) -Suche in der Liste.

Hier ist ein LINQPad- Snippet:

var list = new List<int> { 1, 3, 2 };
var index = list.FindIndex(i => i == 2); // like Where/Single
if (index >= 0) {   // ensure item found
    list.RemoveAt(index);
}
list.Dump();        // results -> 1, 3

Viel Spaß beim Codieren.


quelle
4

Sie geben nicht an, welche Art von Liste, aber die generische Liste kann entweder die RemoveAt(index)Methode oder die Remove(obj)Methode verwenden:

// Remove(obj)
var item = resultList.Single(x => x.Id == 2);
resultList.Remove(item);

// RemoveAt(index)
resultList.RemoveAt(1);
mgnoonan
quelle
4

Einfacher:

resultList.Remove(resultList.Single(x => x.Id == 2));

Es ist nicht erforderlich, ein neues var-Objekt zu erstellen.

Javier Andres Caicedo
quelle
0

... oder nur resultlist.RemoveAt(1)wenn Sie den Index genau kennen.

Vlad
quelle
0
{
    class Program
    {
        public static List<Product> list;
        static void Main(string[] args)
        {

            list = new List<Product>() { new Product() { ProductId=1, Name="Nike 12N0",Brand="Nike",Price=12000,Quantity=50},
                 new Product() { ProductId =2, Name = "Puma 560K", Brand = "Puma", Price = 120000, Quantity = 55 },
                 new Product() { ProductId=3, Name="WoodLand V2",Brand="WoodLand",Price=21020,Quantity=25},
                 new Product() { ProductId=4, Name="Adidas S52",Brand="Adidas",Price=20000,Quantity=35},
                 new Product() { ProductId=5, Name="Rebook SPEED2O",Brand="Rebook",Price=1200,Quantity=15}};


            Console.WriteLine("Enter ProductID to remove");
            int uno = Convert.ToInt32(Console.ReadLine());
            var itemToRemove = list.Find(r => r.ProductId == uno);
            if (itemToRemove != null)
                list.Remove(itemToRemove);
            Console.WriteLine($"{itemToRemove.ProductId}{itemToRemove.Name}{itemToRemove.Brand}{itemToRemove.Price}{ itemToRemove.Quantity}");
            Console.WriteLine("------------sucessfully Removed---------------");

            var query2 = from x in list select x;
            foreach (var item in query2)
            {
                /*Console.WriteLine(item.ProductId+" "+item.Name+" "+item.Brand+" "+item.Price+" "+item.Quantity );*/
                Console.WriteLine($"{item.ProductId}{item.Name}{item.Brand}{item.Price}{ item.Quantity}");
            }

        }

    }
}
Prabhakaran M.
quelle