sintaxis multiple expresiones español c# linq lambda

c# - multiple - ¿Eliminar instancias de una lista usando LINQ o Lambda?



linq c# (7)

Ahora vengo a una etapa para obtener todos mis datos como una lista en caché (objetos) y mi siguiente paso es eliminar algunas instancias de la lista.

Normalmente, lo haría eliminando así:

List<T> list; List<T2> toBeRemovedItems; // populate two lists foreach(T2 item in toBeRemovedItems) { list.Remove(delegate(T one) { // build a condition based on item // return true or false }); }

Para ser más específico, realmente construyo o llego a la lista BeRemvoedItems de una clase dinámica (no una clase formal definida). Por ejemplo, la clase T es algo así como MyClass y los códigos para eliminar son:

class MyClass<C> { public string Value1 { get; set; } public int Value2 { get; set; } public C ObjectC { get; set; } } .... List<MyClass<C>> list; // populate list // populate toBeRemovedItems. Here is an example of hard-coded codes: var toBeRemovedLItems = new[] { new { Value1="a", Value2 = 1}, new { Value2="x", Value2 = 10}, ... }; // toBeRemovedItems may be the result of Select from a collection foreach(var item in toBeRemovedLItems) { list.Remove(delegate(MyClass one) { return one.Value1 = item.Value1 && one.Value2 < item.Value2; }); }

Traté de buscar el método Remove() en la interfaz IEnumerable de MSDN, pero no puedo encontrar el método de Remove() allí (tiene sentido que IEnumerable se use solo para la enumeración). En la clase List, hay varios métodos Remove(...) sobrecargados. No estoy seguro de si hay alguna forma alternativa de eliminar elementos de una lista mediante el uso de expresiones LINQ o Lambda.

Por cierto, pensé en una forma de hacer una consulta en una lista para obtener un subconjunto o una nueva lista IEnumerable con las condiciones Where, similar a mover elementos de una lista. Sin embargo, prefiero eliminar elementos de mi lista en caché, y en algunos casos simplemente no puedo restablecer la propiedad de la lista en una clase a una nueva lista (por ejemplo, un conjunto privado).


Estoy de acuerdo con la sugerencia de Jared de filtrar ciertos artículos, pero parece que join a Value1 sería un enfoque más eficiente:

var res = from item1 in list join item2 in toBeRemovedList on item1.Value1 equals item2.Value1 where item1.Value2 >= item2.Value2 select item1;

Actualización: Aparentemente no logro comprender la lectura, nuevo enfoque:

var removeDict = toBeRemovedList.ToDictionary(i => i.Value1, i => i.Value2); list.RemoveAll(item => { int itemToRemoveValue2; if(removeDict.TryGetValue(item.Value1, out itemToRemoveValue2)) return item.Value2 < itemToRemoveValue2; return false; });

Por supuesto, sería aún mejor si su lista para eliminar pudiera comenzar como un diccionario. En última instancia, solo estamos tratando de hacer que nuestra Value1 en Value1 más eficiente.


Para las colecciones que no son listas (no se puede exponer RemoveAll ), puede eliminar elementos con un solo liner.

Para reemplazar en línea, solo genere una lista de elementos para eliminar, luego ejecútelo y ejecute eliminar código.

var dictionary = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}}; dictionary .Where(where_item => ((where_item.Key == "foo") && (where_item.Value == "0")) || ((where_item.Key == "boo") && (where_item.Value == "1")) ) .ToList() .ForEach(remove_item => { dictionary.Remove(remove_item.Key); });

Para reemplazar en copia, solo genere un enumerable filtrado y devuelva una nueva copia.

var dictionary0 = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}}; var dictionary1 = dictionary0 .Where(where_item => ((where_item.Key == "foo") && (where_item.Value == "0")) || ((where_item.Key == "boo") && (where_item.Value == "1")) ) .ToDictionary(each_item => each_item.Key, each_item => each_item.Value);


Puede usar el método RemoveAll :

MyClass one; //initialize MyClass list.RemoveAll(item => one.Value1 == item.Value1 && one.Value2 < item.Value2);


Puede utilizar el método Where de LINQ para filtrar valores que no deberían formar parte de la lista. El resultado es un IEnumerable<T> con los elementos eliminados.

var res = list.Where(item => !(one.Value1 == item.Value1 && one.Value2 < item.Value2));

Esto no actualizará la instancia de la List<T> , sino que creará una nueva IEnumerable<T> con los valores eliminados.


Si recibo la pregunta correctamente, produzco un conjunto único de dos listas.

Para esto, puedes usar lo siguiente

List list1; List list2;

List list3 = list1.Except (list2)

La lista3 contendrá elementos únicos.


Tal vez estás tratando de hacer algo como esto?

List<T> firstList; List<T2> toBeRemovedItems; List<T> finalList; foreach(T item in firstList) { toBeRemovedItems = CheckIfWeRemoveThisOne(item.Number, item.Id); if (toBeRemovedItems == null && toBeRemovedItems.Count() == 0) finalList.Add(item); }

Así es como logré resolver un problema al deshacerme de duplicados entre una List<ViewModel> y una List<Model> . Utilicé la función CheckIfWeRemoveThisOne para verificar si el artículo. item.Number pertenecía a algún otro elemento, usando la ID como característica definitoria. Si encontró otro elemento (un duplicado), en lugar de tratar de eliminarlo de la lista original (que en primer lugar List<ViewModel> un List<Model> y en mi función se me daba una List<ViewModel> , entonces tenía mis dudas en cuanto a cómo podría hacerlo, de todos modos), acabo de crear una nueva lista, agregando el resultado si se comprobaba que estaba bien.


foreach(var item in toBeRemovedLItems) { list.RemoveAll(one => one.Value1 == item.Value1 && one.Value2 < item.Value2); }

Demasiado tarde otra vez. Oh bien.