Estoy buscando una forma muy rápida de filtrar una colección en C #. Actualmente estoy usando colecciones genéricas List <object>, pero estoy abierto a usar otras estructuras si funcionan mejor.
Actualmente, estoy creando una nueva Lista <objeto> y recorriendo la lista original. Si el criterio de filtrado coincide, pongo una copia en la nueva lista.
¿Hay una mejor manera de hacer esto? ¿Hay alguna forma de filtrar en el lugar para que no se requiera una lista temporal?
c#
collections
filtering
Jason Z
fuente
fuente
Respuestas:
Si usa C # 3.0, puede usar linq, mucho mejor y mucho más elegante:
Si no puede encontrar el
.Where
, eso significa que necesita importarusing System.Linq;
en la parte superior de su archivo.fuente
.Where(predefinedQuery)
lugar de usar.Where(x => x > 7)
?public bool predefinedQuery(int x) { return x > 7; }
. Entonces tu.Where(predefinedQuery)
funcionaría bien.Aquí hay un bloque de código / ejemplo de algunos filtros de listas usando tres métodos diferentes que reuní para mostrar el filtrado de listas basado en Lambdas y LINQ.
fuente
List<T>
tiene unFindAll
método que hará el filtrado por usted y devolverá un subconjunto de la lista.MSDN tiene un gran ejemplo de código aquí: http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx
EDITAR: Escribí esto antes de tener una buena comprensión de LINQ y el
Where()
método. Si escribiera esto hoy, probablemente usaría el método que Jorge menciona arriba. SinFindAll
embargo, el método aún funciona si está atascado en un entorno .NET 2.0.fuente
Puede usar IEnumerable para eliminar la necesidad de una lista temporal.
donde Matches es el nombre de su método de filtro. Y puedes usar esto como:
Esto llamará a la función GetFilteredItems cuando sea necesario y, en algunos casos, si no usa todos los elementos de la colección filtrada, puede proporcionar una buena ganancia de rendimiento.
fuente
Para hacerlo en su lugar, puede usar el método RemoveAll de la clase "List <>" junto con una clase personalizada "Predicate" ... pero todo lo que hace es limpiar el código ... bajo el capó está haciendo lo mismo Lo que eres ... pero sí, lo hace en su lugar, así que haces lo mismo con la lista temporal.
fuente
Puede usar el método FindAll de la Lista, que proporciona un delegado para filtrar. Sin embargo, estoy de acuerdo con @ IainMH en que no vale la pena preocuparse demasiado a menos que sea una lista enorme.
fuente
O, si lo prefiere, use la sintaxis de consulta especial proporcionada por el compilador C # 3:
fuente
Usar LINQ es relativamente mucho más lento que usar un predicado proporcionado al
FindAll
método Listas . También tenga cuidado con LINQ ya que la enumeración de lalist
no se ejecuta realmente hasta que acceda al resultado. Esto puede significar que, cuando cree que ha creado una lista filtrada, el contenido puede diferir de lo que esperaba cuando realmente lo leyó.fuente
Si su lista es muy grande y está filtrando repetidamente, puede ordenar la lista original en el atributo de filtro, búsqueda binaria para encontrar los puntos de inicio y finalización.
Tiempo inicial O (n * log (n)) luego O (log (n)).
El filtrado estándar tomará O (n) cada vez.
fuente