Як видалити елемент із списку в C #?


190

У списку результатів я зберігається таким чином:

var resultlist = results.ToList();

Це виглядає приблизно так:

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

Як видалити ідентифікатор 2 зі списку?

Відповіді:


367

List<T> є два способи, якими ви можете скористатися.

RemoveAt (int index) може бути використаний, якщо ви знаєте індекс елемента. Наприклад:

resultlist.RemoveAt(1);

Або ви можете використовувати Remove (T елемент) :

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

Якщо ви не впевнені, що елемент дійсно існує, ви можете використовувати SingleOrDefault . SingleOrDefaultповернеться, nullякщо предмета немає ( Singleвикине виняток, коли він не може знайти предмет). Обидва будуть кидати, коли є повторюване значення (два елементи з однаковим id).

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

5
ну, ніж можливоvar itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove);
Влад

1
Чи не повинно бути цього resultlist.Items.RemoveAt(1);?
DreamTeK

49

Коротка відповідь:
Видалити (зі списку results)

results.RemoveAll(r => r.ID == 2);видалить елемент з ID 2 в results(на місці).

Фільтр (без вилучення з оригінального списку results):

var filtered = result.Where(f => f.ID != 2);повертає всі елементи, окрім одного з ідентифікатором 2

Детальна відповідь:

Я думаю, що .RemoveAll()це дуже гнучко, тому що ви можете мати список ідентифікаторів елементів, які ви хочете видалити - зверніть увагу на наступний приклад.

Якщо у вас є:

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

і призначив деякі значення resultsтаким чином:

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

Тоді ви можете визначити список ідентифікаторів, які потрібно видалити:

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

І просто скористайтеся цим, щоб видалити їх:

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

Він видалить пункти 2 і 3 і збереже пункти 1 і 4 - як зазначено в removeList. Зверніть увагу, що це відбувається на місці, тому не потрібно додаткового призначення.

Звичайно, ви також можете використовувати його для окремих предметів, таких як:

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

де він видалить Білл з ідентифікатором 4 у нашому прикладі.


DotNetFiddle: запустити демонстрацію


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

У мене є маленький помічник Linq, який мені подобається, який легко здійснити, і він може зробити запити в умовах "де немає" трохи легшими для читання:

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
Інший подібний підхід (який використовує присудок) полягає у використанні List.FindIndex/ List.RemoteAt(який має "приємну" чи "не дуже приємну" функцію мутації).

Правда, але будьте обережні про те , що операція Ліста є мутує. Список використовує масив за кадром, і він може відтворити свій масив з меншою або більшою ємністю, коли вважає, що це необхідно. Зазвичай видалення - це місцева мутація існуючого масиву.
KeithS

Це безпечна нитка, і для її простоти ви можете просто використовувати SingleOrDefault, її не потрібно містити в статичному методі

Ніхто не сказав, що це безпечно для потоків (і чи залежить це від того, що нитки повинні робити; може насправді краще надавати іншим конструкторам пам’яті робочій нитці, а не дозволяти їм працювати на одній одночасній колекції ), і ОП бажає всіх записів, за винятком тієї, що відповідає предикату, тому SingleOrDefault насправді повертає саме те, чого вони не хочуть. "Статичний метод" насправді є методом розширення, як і більшість Linq, і він працює, коли те, що ви не хочете (один елемент чи багато), визначити простіше, ніж те, що ви робите.
KeithS

5

Є й інший підхід. Він використовує List.FindIndexі List.RemoveAt.

Хоча я, мабуть, використовував рішення, представлене KeithS (просто простий Where/ ToList), цей підхід відрізняється тим, що він мутує оригінальний об'єкт списку. Це може бути хорошою (або поганою) "особливістю" залежно від очікувань.

У будь-якому випадку FindIndex(у поєднанні із захистом) гарантує, що RemoveAtволя буде правильною, якщо в ідентифікаторах є прогалини або впорядкування неправильне тощо, а використання RemoveAt(vs Remove) дозволяє уникнути повторного пошуку O (n) через список.

Ось фрагмент LINQPad :

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

Щасливе кодування.


4

Ви не вказали , який список, але загальний список можна використовувати або RemoveAt(index)метод, або Remove(obj)метод:

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

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


0

... або просто resultlist.RemoveAt(1)якщо ви точно знаєте індекс.


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

        }

    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.