2009-08-07 180 views
9

假設我有一個字符串的集合:生成逗號分隔值

"foo" 
"bar" 
"xyz" 

而且我想生成從列表中逗號分隔值成類似:

"foo, bar, xyz" 

通知缺乏「, 「 最後。

據我所知,有幾十個的方式來產生這一點:

  • 使用for循環和的String.format()或StringBuilder的。
  • 使用整數計數器和刪除結束「‘如果值> 0
  • 不要放’,」對我有什麼權利首輪

示例代碼現在:

if (strs.Count() > 0) 
{ 
    var sb = new StringBuilder(); 
    foreach (var str in strs) 
    sb.AppendFormat("{0}, ", str); 
    return sb.Remove(0, 2).ToString(); 
} 

什麼是上述場景高度可重用的最佳代碼,爲什麼?

回答

4

的string.join是正確的答案,但在一個IEnumerable的情況下,LINQ的往往是比較短的循環:

someStringCollection.Aggregate((first, second) => first + ", " + second); 
+0

LINQ的好用法! – 2009-08-12 14:46:54

26

您想要使用存在於BCL中的string.Join方法來達到此目的。

例子:

var myArray = new string[] { "one", "two", "three" }; 
var output = string.Join(", ", myArray); 

或者,如果你使用.NET 3.5,你可以用任何IEnumerable<string>這樣做:

var output = string.Join(", ", myEnumerable.ToArray()); 

(請注意,這不給最好儘管它顯然仍然是'O(n)',並且幾乎適用於所有情況)。現在

,如果你的枚舉是string類型(一般的IEnumerable<T>)的不是,你可以只使用Select方法將結果轉換成字符串,例如

var output = string.Join(", ", myEnumerable.Select(e => e.ToString()).ToArray()); 

我不知道,如果你正在處理可能潛在包含逗號自己的價值觀,但是這可以通過周圍的引號(")括起來進行工作,並逃離報價,同樣到CSV格式。

var output = string.Join(", ", items.Select(x => x.Contains(",") ? 
    "\"" + x.Replace("\"", "\"\"") + "\"" : x); 

當然,再次分裂它們是一個稍微triciker任務,這需要一點正則表達式。

+1

嗯...我不知道這個函數存在(使我的問題看起來很糟糕)。 – 2009-08-07 14:57:30

+0

@阿德里安:不用擔心。如果你不是來自.NET的背景,那麼在框架中發現新事物並不總是直截了當 - 這是一個建立熟悉感的過程。 – Noldorin 2009-08-07 15:00:04

+1

這就是問題所在,自從第一個版本以來,我一直在做.NET。咄。 – 2009-08-07 15:00:55

2

使用

string s = string.Join (",", new string[] {"aaa", "bbb", "ccc"}); 
3
string finalstr = String.Join(",", strs); 
0

如果你有一個字符串數組,去Noldorin的解決方案。

但是,如果它的一些其他集合類型,我可能做到這一點:

if (strs.Count() > 0) 
{ 
    var sb = new StringBuilder(); 
    foreach (var str in strs) 
    sb.AppendFormat("{0} {1}", (0 == sb.Length ? "" : ","), str); 
    return sb.ToString(); 
} 
4

正如其他人所說:String.Join通常做到這一點的最好辦法。但是如果你只有一個IEnumerable而不是數組呢?也許你有代碼來枚舉這些,因爲你使用延遲執行從文件中讀取它們。在這種情況下,String.Join並不是很好,因爲你必須遍歷一次這兩個字符串來創建數組,並且一次加入數組。在這種情況下,你想要更多的東西是這樣的:

public static string ToDelimitedString(this IEnumerable<string> source, string delimiter) 
{ 
    string d = ""; 
    var result = new StringBuilder(); 

    foreach(string s in source) 
    { 
     result.Append(d).Append(s); 
     d = delimiter; 
    } 
    return result.ToString(); 
} 

這將執行幾乎還有的string.join,並在更普遍的情況運作。然後,給定一個字符串數組或任何其他的IEnumerable,你可以這樣調用:

string finalStr = MyStrings.ToDelimitedString(","); 
+0

是的,這顯然是更常見的情況。 IEnumerable 比string []。 – 2009-08-07 15:06:04

+0

+1'結果。附加(d)。附加(s)'很有意思......從來沒有想到這一點。看看目前這個簡單的任務有多少種不同的方式會很有幫助。 – 2009-08-07 15:08:00

+0

非常酷的事情是抖動通常會優化額外的分配,所以代碼確實_exactly_你想要它。 – 2009-08-07 15:09:14