可能重复:
LINQ列表到句子格式(插入逗号&"和")
想象一下这些输入和结果:
[] -> ""
["Hello World!"] -> "Hello World!"
["Apples", "bananas"] -> "Apples, and bananas" (put your grammar books away)
["Lions", "Tigers", "Bears"] -> "Lions, Tigers, and Bears" (oh my!)
Run Code Online (Sandbox Code Playgroud)
现在,想象一下输入都是IEnumerable<string>.有什么好处(哪里好可能包含"小而整齐","易于理解","使用LINQ的全部功能",或其他只要有理由)在C#中编写一个函数来执行此操作?我真的想避免"强制循环"方法.
我目前的方法如下:
string Commaize (IEnumerable<string> list) {
if (list.Count() > 1) {
list = list.Take(list.Count() - 2).Concat(
new[] { list.Reverse().Take(2).Reverse()
.Aggregate((a, b) => a + " and " + b) });
}
return String.Join(", ", list.ToArray());
}
Run Code Online (Sandbox Code Playgroud)
但它感觉不是很"好".这是针对.NET3.5所以ToArray()这里需要这个位.如果list为null,则结果为UB.
与其他答案(CodeInChaos发布的答案除外)不同,此实现仅枚举输入序列一次.如果枚举它的成本很高(例如数据库查询,Web服务调用......),这可能很重要.
string Commaize (IEnumerable<string> list)
{
string previous = null;
StringBuilder sb = new StringBuilder();
foreach(string s in list)
{
if (previous != null)
sb.AppendFormat("{0}, ", previous);
previous = s;
}
if (previous != null)
{
if (sb.Length > 0)
sb.AppendFormat("and {0}", previous);
else
sb.Append(previous);
}
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)