2009-11-10 3 views
7

Ho un array di stringhe che sto aggiungendo a un generatore di stringhe tramite LINQ.LINQ da aggiungere a uno StringBuilder da una stringa []

Quello che sto praticamente cercando di dire è "Per ogni elemento in questo array, aggiungere una riga a questo StringBuilder".

Posso farlo abbastanza facilmente utilizzando un ciclo foreach tuttavia il seguente codice non sembra fare nulla. Cosa mi manca?

stringArray.Select(x => stringBuilder.AppendLine(x)); 

Dove come questo funziona:

foreach(String item in stringArray) 
{ 
    stringBuilder.AppendLine(item); 
} 
+0

non userò il comando .Select ... non è disponibile il comando ForEach? – sebagomez

+0

Ho rinominato StringBuilder e StringArray per utilizzare un carattere in minuscolo. Giusto per chiarire che mi riferisco alle variabili di istanza e non ai tipi. –

+0

sì, è ... http://msdn.microsoft.com/en-us/library/zecdkyw2.aspx :) – sebagomez

risposta

18

Se ti ostini a farlo in un modo LINQy:

StringBuilder builder = StringArray.Aggregate(
          new StringBuilder(), 
          (sb, s) => sb.AppendLine(s) 
         ); 

In alternativa, come Luke rilevare in un commento su un altro post, si potrebbe dire

Array.ForEach(StringArray, s => stringBuilder.AppendLine(s)); 

La ragione per cui Select fa non funziona perché Select è per la proiezione e la creazione di una IEnumerable della proiezione. Quindi la riga di codice

StringArray.Select(s => stringBuilder.AppendLine(s)) 

non scorrere i StringArray chiamando stringBuilder.AppendLine(s) ad ogni iterazione. Piuttosto, crea uno IEnumerable<StringBuilder> su cui è possibile enumerare.

Suppongo che si possa dire

var e = stringArray.Select(x => stringBuilder.AppendLine(x)); 
StringBuilder sb = e.Last(); 
Console.WriteLine(sb.ToString()); 

ma che è davvero orribile.

+0

Grazie Jason. La tua risposta spiega perché il metodo Select non ha raggiunto il risultato che volevo e perché il metodo foreach stava funzionando. Continuerò con il foreach. Ero davvero curioso di sapere cosa mi mancasse. Adesso lo so. –

+0

È l'ultimo() garantito per iterare? Piuttosto che recuperare stringArray [stringArray.count-1]? Penso che avrei preferito ToList(); – Taemyr

0

StringArray.DoForAll (x => StringBuilder.AppendLine (x));

+0

Che cos'è 'DoForAll'? – jason

+0

Siamo spiacenti, ho avuto questo metodo di estensione per così tanto tempo, ho dimenticato che non fa parte del framework. \t CommonExtensions classe public static \t { \t \t DoForAll public static void (questo IEnumerable articoli, Azione azione) \t \t \t dove T: classe \t \t { \t \t \t se (azione == null) \t \t \t \t lanciare una nuova ArgumentNullException ("azione"); \t \t \t foreach (var item in articoli) \t \t \t \t azione (voce); \t \t \t \t}} – vladhorby

+0

@vladhorby: Un punto di vista sul perché 'DoForAll' e altre estensioni equivalenti non sono implementate: http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs -foreach.aspx – jason

6

Utilizzare il metodo di estensione "PerOgni" anziché "Seleziona".

stringArray.ForEach(x => stringBuilder.AppendLine(x));