2013-01-02 12 views
14

Chcę utworzyć rozdzielaną przecinkami listę w C# z napisem "i" jako ostatnim separatorem.Lista rozdzielana przecinkami z "i" zamiast ostatniego przecinka

string.Join(", ", someStringArray) 

spowoduje ciąg jak ten

Apple, Banana, Pear 

lecz chcę, żeby wyglądać tak:

Apple, Banana and Pear 

Czy istnieje prosty sposób aby to osiągnąć z Linq i bez użycia za pomocą pętli?

+0

Czy przedmioty muszą pojawić się w tej samej kolejności, w jakiej się znajdują, czy możemy je ponownie rozmieścić? –

+0

Powinny być w tej samej kolejności. – bytecode77

+4

'i bez używania pętli' - jak dowodzą odpowiedzi, nie potrzebujesz do tego jawnych pętli. Jednak pętle nie są zła, a LINQ naprawdę po prostu generuje pętle dla ciebie. –

Odpowiedz

22

można zrobić Dołącz wszystkich przedmiotów z wyjątkiem ostatniego, a następnie ręcznie dodać ostatni element:

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); 
     } 
    } 
} 

Jak widać, jest sprawdzenie ilości przedmiotów i decyduje, czy jest to konieczne aby dodać część "i".

+1

Dobrze, ale co, jeśli lista zawiera mniej niż dwa elementy? –

+1

Następnie musimy użyć tego: string days = string.Join (",", notSentDays.Take (notSentDays.Count - 1)) + (notSentDays.Count == 1? "": "And") + notSentDays .Ostatni, ubiegły, zeszły(); – bytecode77

+0

Wolę używać przeciążenia 'string, string [], int, int' niż przeciążenie' IEnumerable '. – Rawling

11

Jednym z możliwych rozwiązań:

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

Zauważ, że to stwierdzenie może iteracyjne someStringArray wiele razy, jeśli nie realizuje ICollection<string> (listy i tablice wdrożyć go). Jeśli tak, utwórz listę z kolekcją i wykonaj zapytanie na ten temat.

+0

Działa idealnie z wpisami 0, 1 i 2+. Miły! –

+1

@JonB: Co masz na myśli mówiąc "działa idealnie z 0 wpisami". Co powinno się stać? –

+0

@MarkByers - zwraca "" zamiast powodować wyjątek lub zwracając coś takiego jak "," lub "i". –

2

Czy istnieje prosty sposób na osiągnięcie tego przy pomocy Linq i bez używania pętli?

Niemożliwe bez pętli. Dla pętli będzie działać najlepiej. Kwerendy LINQ będą używać wielu pętli.

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

Bardzo łatwe do odczytania i zrozumienia. – SoftwareCarpenter

+0

Cóż, wiele pętli może mieć problem z wydajnością, jeśli lista była wystarczająco długa. Ponieważ istnieje około 5 wpisów, wydajność nie ma znaczenia. Powodem, dla którego używam Linq jest unikanie kodu spaghetti. Na tym projekcie pracuje około 10 osób, więc nie możemy wymieniać wydajności w taki sposób, aby była czytelna. Ale dziękuję za odpowiedź. – bytecode77

+2

@Devils, Jeśli istnieje wiele wpisów Użyj 'StringBuilder' zamiast' String'. W przeciwnym razie jest to najbardziej wydajne rozwiązanie niż jakiekolwiek inne zapytanie "LINQ". Zawsze staram się robić wszystko (jak to jest możliwe do odczytania) w LINQ, ale gdy pojawiają się problemy z wydajnością, łatwo jest napisać najgorszy kod za pomocą LINQ> – Tilak

Powiązane problemy