Digamos que tengo una lista de algunos valores de columna que provienen de una tabla, ¿cómo elimino cadenas vacías y valores duplicados? Consulte el siguiente código:
List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();
Esto es lo que acabo de codificar, pero el código de Amiram es mucho más elegante, así que elegiré esa respuesta así es como lo hice:
DataTable dtReportsList = someclass.GetReportsList();
if (dtReportsList.Rows.Count > 0)
{
List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();
dtList.RemoveAll(x=>x == "");
dtList = dtList.Distinct().ToList();
rcboModule.DataSource = dtList;
rcboModule.DataBind();
rcboModule.Items.Insert(0, new RadComboBoxItem("All", "All"));
}
Respuestas:
dtList = dtList.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList()
Supuse que la cadena vacía y los espacios en blanco son como nulos. Si no, puede usar
IsNullOrEmpty
(permitir espacios en blanco), os != null
fuente
Distinct
no lo hagan y que permitan optimizarlos?La respuesta de Amiram es correcta, pero Distinct () tal como se implementó es una operación N 2 ; para cada elemento de la lista, el algoritmo lo compara con todos los elementos ya procesados y lo devuelve si es único o lo ignora en caso contrario. Podemos hacerlo mejor.
Una lista ordenada se puede deducir en tiempo lineal; si el elemento actual es igual al elemento anterior, ignórelo; de lo contrario, devuélvalo. La clasificación es NlogN, por lo que incluso teniendo que ordenar la colección, obtenemos algún beneficio:
public static IEnumerable<T> SortAndDedupe<T>(this IEnumerable<T> input) { var toDedupe = input.OrderBy(x=>x); T prev; foreach(var element in toDedupe) { if(element == prev) continue; yield return element; prev = element; } } //Usage dtList = dtList.Where(s => !string.IsNullOrWhitespace(s)).SortAndDedupe().ToList();
Esto devuelve los mismos elementos; simplemente están ordenados.
fuente
Distinct
usa hash y debería estar más cerca de O (N) que de O (N ^ 2). fuenteLa solución de Amiram Korach es realmente ordenada. Aquí hay una alternativa en aras de la versatilidad.
var count = dtList.Count; // Perform a reverse tracking. for (var i = count - 1; i > -1; i--) { if (dtList[i]==string.Empty) dtList.RemoveAt(i); } // Keep only the unique list items. dtList = dtList.Distinct().ToList();
fuente
Para simplificar la solución de Amiram Korach :
dtList.RemoveAll(s => string.IsNullOrWhiteSpace(s))
No es necesario utilizar Distinct () o ToList ()
fuente