Eliminar elementos de una lista en otra


Estoy tratando de averiguar cómo atravesar una lista genérica de elementos que quiero eliminar de otra lista de elementos.

Así que digamos que tengo esto como un ejemplo hipotético

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

Quiero recorrer list1 con un foreach y eliminar cada elemento de List1 que también está contenido en List2.

No estoy muy seguro de cómo hacerlo, ya que foreach no está basado en índices.

 148
Author: radbyx, 2010-04-30

8 answers

Puedes usar Excepto :

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();

Probablemente ni siquiera necesites esas variables temporales:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

Tenga en cuenta que Except no modifica ninguna lista - crea una nueva lista con el resultado.

 275
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 15:33:26

No necesita un índice, ya que la clase List<T> le permite eliminar elementos por valor en lugar de índice utilizando la función Remove.

foreach(car item in list1) list2.Remove(item);
 27
Author: Adam Robinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 15:15:53

Recomendaría usar los métodos de extensión LINQ. Puedes hacerlo fácilmente con una línea de código como esta:

list2 = list2.Except(list1).ToList();

Esto supone, por supuesto, que los objetos en list1 que está eliminando de list2 son la misma instancia.

 21
Author: Berkshire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 15:18:01

Podrías usar LINQ, pero yo iría con el método RemoveAll. Creo que es la que mejor expresa tu intención.

var integers = new List<int> { 1, 2, 3, 4, 5 };

var remove = new List<int> { 1, 3, 5 };

integers.RemoveAll(i => remove.Contains(i));
 13
Author: João Angelo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 15:22:55

En mi caso tenía dos listas diferentes, con un identificador común, algo así como una clave foránea. La segunda solución citada por "nzrytmn":

var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();

Era el que mejor encajaba en mi situación. Necesitaba cargar una lista desplegable sin los registros que ya se habían registrado.

¡Gracias !!!

Este es mi código:

t1 = new T1();
t2 = new T2();

List<T1> list1 = t1.getList();
List<T2> list2 = t2.getList();

ddlT3.DataSource= list2.Where(s => !list1.Any(p => p.Id == s.ID)).ToList();
ddlT3.DataTextField = "AnyThing";
ddlT3.DataValueField = "IdAnyThing";
ddlT3.DataBind();
 10
Author: Gabriel Santos Reis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-07 15:36:31
list1.RemoveAll(l => list2.Contains(l));
 9
Author: Alexandre Castro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-08 18:44:08

Solución 1: Puedes hacer así:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

Pero en algunos casos puede que esta solución no funcione. si no es trabajo puedes usar mi segunda solución .

Solución 2:

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

Pretendemos que list1 es su lista principal y list2 es su lista secundaria y desea obtener elementos de list1 sin elementos de list2.

 var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();
 5
Author: nzrytmn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-01 06:08:44

Aquí tienes..

    List<string> list = new List<string>() { "1", "2", "3" };
    List<string> remove = new List<string>() { "2" };

    list.ForEach(s =>
        {
            if (remove.Contains(s))
            {
                list.Remove(s);
            }
        });
 -4
Author: Ian P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-30 15:18:18