Вопрос по list, c# – Как удалить элемент из списка в C #?

131

У меня есть список сохраненных в списке результатов следующим образом:

<code>var resultlist = results.ToList();
</code>

Это выглядит примерно так:

<code>ID FirstName  LastName
-- ---------  --------
1  Bill       Smith
2  John       Wilson
3  Doug       Berg
</code>

Как мне удалить идентификатор 2 из списка?

Ваш Ответ

5   ответов
263

List<T> @ есть два метода, которые вы можете использовать.

RemoveAt (int index) можно использовать, если вы знаете индекс предмета. Например

resultlist.RemoveAt(1);

Или ты можешь использоватьRemove (T item):

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);
Разве это не должно бытьresultlist.Items.RemoveAt(1); ? DreamTeK
хорошо, чем, может быть,var itemsToRemove = resultlist.Where(r => r.Id == 2); foreach (var itemToRemove in ItemsToRemove) resultList.Remove(itemToRemove); Vlad
35
resultList = results.Where(x=>x.Id != 2).ToList();

который мне нравится, его легко реализовать, и он может немного облегчить чтение запросов с условиями "где нет":

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();
Другой похожий подход (использующий предикат) заключается в использованииList.FindIndex/List.RemoteAt (которая имеет «симпатичную» или «не очень приятную» функцию мутации). user166390
Никто не сказал, что это потокобезопасно (и зависит ли это от того, что потоки должны делать; на самом деле может быть предпочтительнее дать рабочему потоку другую конструкцию в памяти, чем позволить всем им работать на одном параллельном компьютере). коллекция), а ОП хочет все записиКром тот, который соответствует предикату, поэтому SingleOrDefault на самом деле вернет именно то, что они Не хочу. «Статический метод» на самом деле является методом расширения, как и большинство Linq, и он работает всякий раз, когда то, что вам не нужно (один или несколько элементов), легче определить, чем то, что вы делаете. KeithS
Правда, но будь осторожен с тем, чтобы сказать, что операция Листаявляетс мутирует. List использует массив за кулисами, и он может воссоздать свой массив с меньшей или большей емкостью, когда он считает это необходимым.Обычн, удаление - это мутация существующего массива на месте. KeithS
Это не потокобезопасно, и для его простоты вы можете просто использовать SingleOrDefault, его не нужно содержать в статическом методе user1043000
22

Краткий ответ
Удалить из спискаresults)

results.RemoveAll(r => r.ID == 2); удалит элемент сID 2 вresults (на месте)

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

var filtered = result.Where(f => f.ID != 2); возвращает все элементы, кроме одного сID 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);

где он удалит Билла с ID 4 в нашем примере.

DotNetFiddle: Запустите демо

3

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

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

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

List.FindIndex а такжеList.RemoveAt.

Пока я бывероятн используйте решение, представленное KeithS (просWhere/ToList) этот подход отличается тем, что он Мутирует исходный объект списка. Это может быть хорошей (или плохой) «функцией» в зависимости от ожиданий.

В любом случае,FindIndex (в сочетании с охраной) обеспечиваетRemoveAt будет правильным, если в идентификаторах есть пробелы или неправильный порядок и т. д., и с использованиемRemoveAt (против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

Счастливое кодирование.

Похожие вопросы