2013-01-02 21 views
14

Voglio creare una lista separata da virgola in C# con la parola "e" come ultimo delimitatore.Elenco separati da virgola con "e" al posto dell'ultima virgola

string.Join(", ", someStringArray) 

si tradurrà in una stringa come questa

Apple, Banana, Pear 

ma invece voglio farlo sembrare come questo:

Apple, Banana and Pear 

C'è un modo semplice per raggiungerlo con LINQ e senza utilizzando loop?

+0

Gli articoli devono apparire nello stesso ordine in cui si trovano attualmente oppure possiamo riordinarli? –

+0

Dovrebbero essere nello stesso ordine. – bytecode77

+4

'e senza usare i cicli' - come dimostrano le risposte, non è necessario un ciclo esplicito per questo. Tuttavia, i loop sono difficilmente malvagi e LINQ sta solo generando i loop per te. –

risposta

22

Si può fare un join su tutti gli elementi tranne l'ultimo e quindi aggiungere manualmente l'ultimo elemento:

using System; 
using System.Linq; 

namespace Stackoverflow 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      DumpResult(new string[] { }); 
      DumpResult(new string[] { "Apple" }); 
      DumpResult(new string[] { "Apple", "Banana" }); 
      DumpResult(new string[] { "Apple", "Banana", "Pear" }); 
     } 

     private static void DumpResult(string[] someStringArray) 
     { 
      string result = string.Join(", ", someStringArray.Take(someStringArray.Length - 1)) + (someStringArray.Length <= 1 ? "" : " and ") + someStringArray.LastOrDefault(); 
      Console.WriteLine(result); 
     } 
    } 
} 

Come si può vedere, non v'è un controllo sulla quantità di oggetti e decide se è necessario aggiungere la parte 'e'.

+1

Bello, ma cosa succede se l'elenco contiene meno di due elementi? –

+1

Quindi, dovremmo utilizzare questo: string days = string.Join (",", notSentDays.Take (notSentDays.Count - 1)) + (notSentDays.Count == 1? "": "E") + notSDays .Ultimo(); – bytecode77

+0

Preferisco usare il sovraccarico di 'string, string [], int, int''' che l'overload' IEnumerable '. – Rawling

11

Una possibile soluzione:

var items = someStringArray; // someStringArray.ToList() if not a ICollection<> 
var s = string.Join(", ", items.Take(items.Count() - 1)) + 
     (items.Count() > 1 ? " and " : "") + items.LastOrDefault(); 

Si noti che questa affermazione può iterare someStringArray più volte se non implementa ICollection<string> (liste e array implementarlo). In tal caso, crea un elenco con la tua raccolta ed esegui la query.

+0

Funziona perfettamente con le voci 0, 1 e 2+. Bello! –

+1

@JonB: Cosa intendi per "funzionare perfettamente con 0 voci". Cosa dovrebbe succedere? –

+0

@MarkByers - restituisce "", piuttosto che causare un'eccezione o restituire qualcosa come "," o "e". –

2

C'è un modo semplice per ottenerlo con Linq e senza utilizzare loop?

Non possibile senza loop. Per il ciclo funzionerà meglio. Le query LINQ utilizzeranno più loop.

string Combine (IEnumerable<string> list) 
    { 
     bool start = true; 
     var last = string.Empty; 
     String str = string.Empty; 

     foreach(var item in list) 
     { 
      if (!start) 
      { 
       str = str + " , " + item; 
       last = item; 

      } 
      else 
      { 
       str = item; 
       start = false; 
      } 

     } 

     if (!string.IsNullOrWhiteSpace(last)) 
     { 
      str = str.Replace(" , " + last, " and " + last); 
     } 

     return str; 
    } 
+0

Molto facile da leggere e capire. – SoftwareCarpenter

+0

Bene, loop multipli potrebbero ottenere un problema di prestazioni se l'elenco fosse abbastanza lungo. Poiché ci sono circa 5 voci, le prestazioni non contano. Il motivo per cui utilizzo Linq è evitare il codice spaghetti. Ci sono circa 10 persone che lavorano a questo progetto, quindi non possiamo scambiare le prestazioni con una leggibilità come questa. Ma grazie per la tua risposta. – bytecode77

+2

@Devils, se ci sono più voci usa 'StringBuilder' invece di' String'. Altrimenti questa è la soluzione più efficiente di qualsiasi altra query 'LINQ'. Cerco sempre di fare tutto (come è leggibile) in LINQ, ma quando arrivano i problemi di performance, è facile scrivere codice peggiore usando LINQ> – Tilak

Problemi correlati