Pregunta

¿Cuál es la forma mejor/más fácil de obtener un recuento de elementos dentro de una colección IEnumerable sin enumerar todos los elementos de la colección?

¿Es posible con LINQ o Lambda?

¿Fue útil?

Solución

Tendrás que enumerar para obtener un recuento.Otras construcciones como la Lista mantienen un conteo continuo.

Otros consejos

La solución depende de por qué no desea enumerar la colección.

Si es porque enumerar la colección puede ser lento, entonces no hay solución que sea más rápida.Es posible que desee considerar el uso de ICollection en su lugar si es posible.A menos que la enumeración sea notablemente lenta (p. ej.lee elementos del disco), aunque la velocidad no debería ser un problema.

Si es porque enumerar la colección requerirá más código, entonces ya se ha escrito para usted en forma de método de extensión .Count().Simplemente use MyEnumerable.Count().

Si es porque desea poder enumerar la colección después de haber contado, entonces el método de extensión .Count() lo permite.Incluso puedes llamar a .Count() en una colección que estás enumerando y continuará desde donde estaba antes del recuento.Por ejemplo:

foreach (int item in Series.Generate(5))
{
    Console.WriteLine(item + "(" + myEnumerable.Count() + ")");
}

dará los resultados

0 (5)

1 (5)

2 (5)

3 (5)

4 (5)

Si es porque la enumeración tiene efectos secundarios (p. ej.escribe en el disco/consola) o depende de variables que pueden cambiar entre contar y enumerar (p. ej.lee desde el disco) [N.B.Si es posible, sugeriría repensar la arquitectura, ya que esto puede causar muchos problemas]. Entonces una posibilidad a considerar es leer la enumeración en un almacenamiento intermitente.Por ejemplo:

List<int> seriesAsList = Series.Generate(5).ToList();

Todo lo anterior supone que no puede cambiar el tipo (es decir,se devuelve desde una biblioteca que no es de su propiedad).Si es posible, es posible que desee considerar cambiar para usar un ICollection o IList (ICollection tiene un alcance más amplio que IList) que tiene una propiedad Count.

En cualquier caso, hay que recorrerlo.Linq ofrece la Count método:

var result = myenum.Count();

Utilizar esta.

IEnumerable list =..........;

list.OfType<T>().Count()

devolverá el conteo.

También está IList o ICollection, si desea utilizar una construcción que aún sea algo flexible, pero que también tenga la característica que necesita.Ambos implican IEnumerable.

También depende de lo que quieras lograr contando.Si está interesado en saber si la colección enumerable tiene algún elemento, puede usar

myEnumerable.Any() sobre myEnumerable.Count() donde el primero producirá el primer elemento y el segundo producirá todos los elementos.

Un IEnumerable tendrá que recorrer cada elemento.para obtener el recuento completo.Si solo necesita verificar si hay uno o más elementos en un IEnumerable, un método más eficiente es verificar si hay alguno.Any() solo verifica que haya un valor y no recorre todo.

IEnumerable myStrings = new List(){"uno","dos", "tres"};

bool hasValues ​​= myStrings.Any();

No es posible con LINQ, ya que llamar a .Count(...) enumera la colección.Si te encuentras con el problema de que no puedes iterar dos veces a través de una colección, intenta esto:

List<MyTableItem> myList = dataContext.MyTable.ToList();
int myTableCount = myList.Count;

foreach (MyTableItem in myList)
{
   ...
}

Si necesita contar y luego realizar un bucle, es mejor que tenga una lista.

Si está utilizando el recuento para comprobar si hay miembros, puede utilizar Any() para evitar enumerar toda la colección.

La mejor solución, según creo, es hacer lo siguiente:

  1. usando System.Linq.Dynamic;
  2. myEnumerable.AsQueryable().Count()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top