C # listesinden öğe nasıl kaldırılır?


192

Sonuç listesinde aşağıdaki gibi saklanan bir liste var:

var resultlist = results.ToList();

Şuna benziyor:

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

Kimlik 2'yi listeden nasıl kaldırabilirim?

Yanıtlar:


368

List<T> kullanabileceğiniz iki yöntem vardır.

Öğenin dizinini biliyorsanız RemoveAt (int index) kullanılabilir. Örneğin:

resultlist.RemoveAt(1);

Veya Kaldır'ı (T öğesi) kullanabilirsiniz :

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

Öğenin gerçekten var olduğundan emin değilseniz, SingleOrDefault kullanabilirsiniz . hiçbir öğe yoksa SingleOrDefaultgeri döner null( Singleöğeyi bulamadığında bir istisna atar). Her ikisi de yinelenen bir değer olduğunda (aynı olan iki öğe id) atılacaktır .

var itemToRemove = resultlist.SingleOrDefault(r => r.Id == 2);
if (itemToRemove != null)
    resultList.Remove(itemToRemove);

5
iyi, belki devar itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove);
Vlad

1
Bu olmamalı resultlist.Items.RemoveAt(1);mı?
DreamTeK

50

Kısa cevap:
Kaldır (listeden results)

results.RemoveAll(r => r.ID == 2);ile öğeyi kaldırır ID 2 yılında results(yerinde).

Filtre (orijinal listeden çıkarmadan results):

var filtered = result.Where(f => f.ID != 2);Kimlik 2 dışındaki tüm öğeleri döndürür

Ayrıntılı cevap:

.RemoveAll()Çok esnek olduğunu düşünüyorum , çünkü kaldırmak istediğiniz öğe kimliklerinin bir listesine sahip olabilirsiniz - lütfen aşağıdaki örneğe bakın.

Eğer varsa:

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

ve bazı değerleri resultsaşağıdaki gibi atadı :

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" },
};

Ardından, kaldırılacak kimliklerin bir listesini tanımlayabilirsiniz:

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

Ve sadece bunları kaldırmak için kullanın:

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

Bu olacak öğeleri 2. ve 3. kaldırmak ve öğeleri 1 ve 4 tutmak - belirttiği şekilde removeList. Bunun gerçekleştiğine dikkat edin , bu yüzden ek bir değerlendirme gerekli değildir.

Tabii ki, aşağıdaki gibi tek öğeler üzerinde de kullanabilirsiniz:

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

burada örneğimizde 4 numaralı Bill'i kaldıracak.


DotNetFiddle: Demoyu çalıştırın


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

Sevmek istediğim küçük bir Linq yardımcısı var ve "nerede olmasın" koşullarıyla okumayı biraz daha kolay hale getirebilir:

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();

1
Benzer bir yaklaşım (yüklem kullanan) kullanmaktır List.FindIndex/ List.RemoteAt(mutasyona uğramış bir operasyon olmanın “hoş” ya da “hoş olmayan” özelliğine sahiptir).

Doğru, ama List operasyon söyleyerek konusunda dikkatli olun edilir mutasyona. Liste, sahnelerin arkasında bir dizi kullanır ve gerekli olduğunu düşündüğünde dizisini daha küçük veya daha büyük bir kapasiteyle yeniden oluşturabilir. Genellikle kaldırma, mevcut dizinin yerinde mutasyonudur.
KeithS

Bu güvenli değildir ve basitliği için sadece SingleOrDefault'u kullanabilirsiniz, statik bir yöntemde yer

Hiç kimse iş parçacığı için güvenli olduğunu söylemedi (ve iş parçacıklarının ne yapması gerektiğine bağlı olup olmadığını; aslında bir iş parçacığına farklı bir bellek içi yapı vermek yerine hepsinin bir eşzamanlı koleksiyonda çalışmasına izin vermek tercih edilebilir. ) ve OP tüm kayıtları isteyen hariç SingleOrDefault gerçeği karşılığında onlar tam olarak ne nedenle, yüklemi eşleşen biri yok istiyorum. "Statik yöntem" aslında birçok Linq gibi bir genişletme yöntemidir ve istemediğinizi (bir öğe veya birçok) tanımlamak, yaptığınızdan daha kolay olduğunda çalışır.
KeithS

5

Başka bir yaklaşım daha var. O kullanır List.FindIndexve List.RemoveAt.

Ben isterken muhtemelen Keiths tarafından sunulan çözüm (sadece basit kullanmak Where/ ToListo değil) bu yaklaşım farklılık mutasyon orijinal liste nesnesi. Bu beklentilere bağlı olarak iyi (veya kötü) bir "özellik" olabilir.

Herhangi bir durumda, FindIndex(bir koruma ile birlikte) temin RemoveAtvb vardır kimlikleri boşluklar ya da sipariş yanlışsa doğru olacak ve kullanma RemoveAt(vs Remove), bir önler ikinci O (n) liste boyunca arama.

İşte bir LINQPad snippet'i:

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

Mutlu kodlama.


4

Ne tür bir liste belirtmezsiniz, ancak genel Liste RemoveAt(index)yöntemi veya Remove(obj)yöntemi kullanabilir:

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

// RemoveAt(index)
resultList.RemoveAt(1);

4

Daha basitleştirilmiş:

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

yeni bir var nesnesi oluşturmaya gerek yoktur.


0

... veya sadece resultlist.RemoveAt(1)dizini tam olarak biliyorsanız.


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}");
            }

        }

    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.