2013-01-02 15 views
14

C# 'de virgülle ayrılmış bir liste oluşturmak ve son sınırlayıcı olarak "ve".Son virgülün yerine "ve" ile virgülle ayrılmış liste

string.Join(", ", someStringArray) 

bu

Apple, Banana, Pear 

gibi bir dize neden olacaktır ama bunun yerine böyle bakmak istiyorum: Linq ve ile bunu başarmak için basit bir yol

Apple, Banana and Pear 

var mı döngüler kullanılarak olmadan?

+0

Öğeler şu anda oldukları sırayla görünmeli mi, yoksa yeniden düzenleyebilir miyiz? –

+0

Aynı sırada olmalılar. – bytecode77

+4

've döngüler kullanmadan - cevapların kanıtladığı gibi, bunun için açık döngülere ihtiyacınız yoktur. Ancak, döngüler pek de kötüler ve LINQ gerçekten sadece sizin için döngüler üretiyor. –

cevap

22

Bir sonuncusu hariç tüm öğeler üzerinde katıl ve daha sonra manuel son öğe eklemek yapabilirsiniz:

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

Gördüğünüz gibi, orada Madde miktarını bir kontrol ve zaten gerekli eğer karar 've' bölümünü eklemek.

+1

Güzel, ama ne liste daha az iki öğe içeriyorsa? –

+1

Sonra, şunu kullanmamız gerekecek: string days = string.Join (",", notSentDays.Take (notSentDays.Count - 1)) + (notSentDays.Count == 1? "": "Ve") + notSentDays .Son(); – bytecode77

+0

"String, string [], int, int' aşırı yüklenmesini" IEnumerable "aşırı yüklemesinden daha çok kullanmayı tercih ediyorum. – Rawling

11

olası bir çözüm: Bu ICollection<string> (listeleri ve diziler uygulamak) uygulamaması halinde bu açıklama someStringArray birden çok kez yinelemek ki

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

Not. Öyleyse, koleksiyonunuzla bir liste oluşturun ve bu sorguyu gerçekleştirin.

+0

0, 1 ve 2+ girişleri ile mükemmel çalışır. Güzel! –

+1

@JonB: "0 girişi ile mükemmel çalışarak" ile ne demek istiyorsun? Ne olmalı? –

+0

@MarkByers - bir istisna oluşturmaya veya "," veya "ve" gibi bir şey döndürmekten ziyade "" döndürür. –

2

Linq'le ve döngüler kullanmadan bunu başarmanın basit bir yolu var mı?

Dönüsüz olarak mümkün değil. Döngü için en iyi çalışır. LINQ sorguları çoklu döngüler kullanacaktır.

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

Okumak ve anlamak çok kolay. – SoftwareCarpenter

+0

Liste çok uzunsa, birden çok döngü bir performans sorunu yaşayabilir. Yaklaşık 5 giriş olduğu için performans önemli değil. Linq kullanmamın nedeni spagetti kodlarından kaçınmaktır. Bu projede yaklaşık 10 kişi çalışıyor, bu yüzden böyle okunabilirlik için performans alışverişi yapamıyoruz. Ama cevabın için teşekkürler. – bytecode77

+2

@Devils, Birden çok giriş varsa, 'String' yerine' StringBuilder' kullanın. Aksi halde bu, diğer tüm LINQ sorgularından daha verimli bir çözümdür. LINQ'da her şeyi (okunabilir olduğu gibi) her zaman yapmaya çalışıyorum, ancak performans sorunları geldiğinde, LINQ kullanarak kötü kod yazmak kolaydır> – Tilak

İlgili konular