Domanda

Qual è il modo migliore/più semplice per ottenere un conteggio degli elementi all'interno di una raccolta IEnumerable senza enumerare tutti gli elementi della raccolta?

Possibile con LINQ o Lambda?

È stato utile?

Soluzione

Dovrai enumerare per ottenere un conteggio.Altri costrutti come List mantengono un conteggio progressivo.

Altri suggerimenti

La soluzione dipende dal motivo per cui non si desidera enumerare la raccolta.

Se è perché l'enumerazione della raccolta potrebbe essere lenta, non esiste una soluzione più veloce.Se possibile, potresti prendere in considerazione l'utilizzo di una ICollection.A meno che l'enumerazione non sia notevolmente lenta (ad es.legge gli elementi dal disco), tuttavia la velocità non dovrebbe essere un problema.

Se è perché l'enumerazione della raccolta richiederà più codice, allora è già stato scritto per te sotto forma di metodo di estensione .Count().Basta usare MyEnumerable.Count().

Se è perché vuoi essere in grado di enumerare la raccolta dopo aver contato, il metodo di estensione .Count() lo consente.Puoi anche chiamare .Count() su una raccolta che stai enumerando e continuerà da dove si trovava prima del conteggio.Per esempio:

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

darà i risultati

0 (5)

1 (5)

2 (5)

3 (5)

4 (5)

Se è perché l'enumerazione ha effetti collaterali (ad es.scrive su disco/console) o dipende da variabili che possono cambiare tra conteggio ed enumerazione (ad es.legge dal disco) [N.B.Se possibile, suggerirei di ripensare l'architettura in quanto ciò può causare molti problemi] quindi una possibilità da considerare è leggere l'enumerazione in un archivio intermittente.Per esempio:

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

Tutto quanto sopra presuppone che non sia possibile modificare il tipo (ad es.viene restituito da una libreria che non possiedi).Se possibile, potresti prendere in considerazione la possibilità di utilizzare un ICollection o un IList (ICollection ha un ambito più ampio di IList) che ha una proprietà Count su di esso.

In ogni caso bisogna percorrerlo in loop.Linq offre il Count metodo:

var result = myenum.Count();

Usa questo.

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

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

restituirà il conteggio.

C'è anche IList o ICollection, se vuoi usare un costrutto che sia ancora piuttosto flessibile, ma abbia anche la funzionalità richiesta.Entrambi implicano IEnumerable.

Dipende anche da cosa vuoi ottenere contando..Se sei interessato a scoprire se la raccolta enumerabile contiene elementi, puoi utilizzare

myEnumerable.Any() su myEnumerable.Count() dove il primo produrrà il primo elemento e il secondo produrrà tutti gli elementi.

Un IEnumerable dovrà scorrere ogni elemento.per ottenere il conteggio completo.Se hai solo bisogno di verificare se sono presenti uno o più elementi in un IEnumerable, un metodo più efficiente è verificare se ce ne sono.Any() controlla solo per vedere che c'è un valore e non esegue il loop di tutto.

IEnumerable myStrings = new List(){"uno","due", "tre"};

bool hasValues ​​= myStrings.Any();

Non è possibile con LINQ, poiché la chiamata a .Count(...) enumera la raccolta.Se riscontri il problema per cui non puoi scorrere una raccolta due volte, prova questo:

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

foreach (MyTableItem in myList)
{
   ...
}

Se hai bisogno di contare e poi ripetere il ciclo, potresti stare meglio con un elenco.

Se stai utilizzando count per verificare la presenza di membri, puoi utilizzare Any() per evitare di enumerare l'intera collezione.

La soluzione migliore, come penso, è fare quanto segue:

  1. utilizzando System.Linq.Dynamic;
  2. myEnumerable.AsQueryable().Count()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top