Usar LINQ para eliminar elementos de una Lista<T>

Resuelto TK. asked hace 15 años • 14 respuestas

Digamos que tengo una consulta LINQ como:

var authors = from x in authorsList
              where x.firstname == "Bob"
              select x;

Dado que authorsListes de tipo List<Author>, ¿cómo puedo eliminar los Authorelementos authorsListque devuelve la consulta authors?

O, dicho de otra manera, ¿cómo puedo eliminar todos los nombres que equivalen a Bob authorsList?

Nota: Este es un ejemplo simplificado a los efectos de la pregunta.

TK. avatar May 12 '09 22:05 TK.
Aceptado

Bueno, sería más fácil excluirlos en primer lugar:

authorsList = authorsList.Where(x => x.FirstName != "Bob").ToList();

Sin embargo, eso simplemente cambiaría el valor de authorsListen lugar de eliminar a los autores de la colección anterior. Alternativamente, puedes usar RemoveAll:

authorsList.RemoveAll(x => x.FirstName == "Bob");

Si realmente necesitas hacerlo basándose en otra colección, usaría HashSet, RemoveAll y Contiene:

var setToRemove = new HashSet<Author>(authors);
authorsList.RemoveAll(x => setToRemove.Contains(x));
Jon Skeet avatar May 12 '2009 16:05 Jon Skeet

Sería mejor usar List<T>.RemoveAll para lograr esto.

authorsList.RemoveAll((x) => x.firstname == "Bob");
Reed Copsey avatar May 12 '2009 16:05 Reed Copsey

Si realmente necesita eliminar elementos, ¿qué pasa con Except()?
Puede eliminar en función de una nueva lista o eliminar sobre la marcha anidando Linq.

var authorsList = new List<Author>()
{
    new Author{ Firstname = "Bob", Lastname = "Smith" },
    new Author{ Firstname = "Fred", Lastname = "Jones" },
    new Author{ Firstname = "Brian", Lastname = "Brains" },
    new Author{ Firstname = "Billy", Lastname = "TheKid" }
};

var authors = authorsList.Where(a => a.Firstname == "Bob");
authorsList = authorsList.Except(authors).ToList();
authorsList = authorsList.Except(authorsList.Where(a=>a.Firstname=="Billy")).ToList();
BlueChippy avatar Nov 19 '2010 13:11 BlueChippy

No puede hacer esto con operadores LINQ estándar porque LINQ proporciona soporte para consultas, no para actualizaciones.

Pero puedes generar una lista nueva y reemplazar la anterior.

var authorsList = GetAuthorList();

authorsList = authorsList.Where(a => a.FirstName != "Bob").ToList();

O puede eliminar todos los elementos en authorsuna segunda pasada.

var authorsList = GetAuthorList();

var authors = authorsList.Where(a => a.FirstName == "Bob").ToList();

foreach (var author in authors)
{
    authorList.Remove(author);
}
Daniel Brückner avatar May 12 '2009 16:05 Daniel Brückner