2009-10-22 9 views
8

Recentemente ho affrontato una domanda di intervista relativa a LINQ.Sequenza vuota in LINQ

Qual è l'uso della sequenza vuota? Ha chiesto "se suppongo di chiederti di usare quello, dove lo collochi?"

 public static IEnumerable<TResult> Empty<TResult>() 
    { 
     yield break; 
    } 

Non ho risposto. L'aiuto è apprezzato.

+2

Come si forma una sequenza vuota? Come si adatta? – Will

+0

+1 per una buona domanda secondo me. –

+0

@Stan Devo ringraziarvi per aver chiarito il mio dubbio. –

risposta

3

È possibile utilizzare questo quando si desidera creare rapidamente un IEnumerable<T> questo modo non c'è bisogno di creare un riferimento a un nuovo List<T> e sfruttare la resa parola chiave.

List<string[]> namesList = 
    new List<string[]> { names1, names2, names3 }; 

// Only include arrays that have four or more elements 
IEnumerable<string> allNames = 
    namesList.Aggregate(Enumerable.Empty<string>(), 
    (current, next) => next.Length > 3 ? current.Union(next) : current); 

Nota l'uso di dell'Unione perché non è un elenconon si può chiamare Aggiungi metodo, ma si potrebbe chiamare dell'Unione su un IEnumerable

+0

È possibile ottenere prestazioni migliori utilizzando Concat anziché Union, a meno che non sia davvero necessario escludere i duplicati. –

+2

Il modo più veloce per unirsi a un gruppo di elenchi come quello che utilizza LINQ è namesList.SelectMany (list => list.Length> 4? List: Enumerable.Empty ()). Distinct(). Farlo con Aggregate e Union è estremamente inefficiente. Aggregate e Concat è migliore ma è ancora O (Nsquared) e O (N) spazio. SelectMany/Distinct è O (N) e O (1) spazio (vengono creati solo 3 oggetti). –

4

Se si dispone di un ciclo che ha aggregato insieme diversi set in un set di risultati, è possibile utilizzarlo per inizializzare la variabile del set di risultati e ripetere/accumulare. Per esempio:

IEnumerable<string> results = Enumerable.Empty<string>(); 

for(....) 
{ 
    IEnumerable<string> subset = GetSomeSubset(...); 

    results = results.Union(subset); 
} 

Senza di vuoto che avrebbe dovuto aver scritto un assegno nulla nella vostra logica ciclo:

IEnumerable<string> results = null; 

for(....) 
{ 
    IEnumerable<string> subset = GetSomeSubset(...); 

    if(results == null) 
    { 
     results = subset; 
    } 
    else 
    { 
     results = results.Union(subset); 
    } 
} 

Non deve solo essere uno scenario di ciclo e non è così deve essere Union (potrebbe essere una funzione aggregata), ma questo è uno degli esempi più comuni.

+0

Grazie mille per aver fatto un eccellente esempio di perdonanza –

+0

Buona risposta alla domanda posta. I lettori devono tenere presente che il mio commento sul rendimento sopra riportato si applica anche a questo codice. L'uso di Union in questo modo è O (Nsquared) perché crea un Set per ogni unione e lo riempie con tutte le stringhe finora. Beh, immagino che sia tecnicamente O (NM). Il punto è che è molto lento e SelectMany/Distinct è molto meglio per questo tipo di scenario. –

Problemi correlati