我需要连接很多字符串并在其中任何一个之间加上逗号。 我有一个字符串列表
"123123123213"
"1232113213213"
"123213123"
我希望得到
"123123123213,1232113213213,123213123"
我想知道实现这一目标的最佳途径是什么。
我可以这样做:
private List<string> stringList = new List<string> {
// a lot of strings in here
"1234567890", "34343434", "4343434" };
string outcome = string.Join(",", stringList.ToArray());
或者也许:
StringBuilder builder = new StringBuilder();
stringList.ForEach(val => {
builder.Append(val);
builder.Append(",");
});
string outcome = builder.ToString();
哪种方式更好?你知道连接字符串的更好方法吗?
答案 0 :(得分:6)
如@Ekkehard所述,请使用string.Join。
但是,您不需要ToArray()
,因为string.Join
的{{1}}超载。
IEnumerable<string>
修改强>
正如@Kobi所说,这只适用于C#4.0。在3.5我会这样做。
List<string> stringList = new List<string>
{ "1234567890", "34343434", "4343434" };
string outcome = string.Join(",", stringList);
答案 1 :(得分:5)
您应该使用string.Join()
,因为:
a)它更具可读性,易维护性和易于使用。
b)它已经在内部使用了StringBuilder
,所以它非常有效(你可以使用Reflector确认自己)。
修改:
string.Join()
使用StringBuilder
作为IEnumerable<T>
输入的一般情况。如果你已经拥有一个数组,那么它会使用一些巫术魔法(包括FastAllocateString()
和UnSafeCharBuffer
)来更快。
答案 2 :(得分:1)
使用Join,因为它不会添加尾随“,”。
答案 3 :(得分:1)
this page上有一个基准测试似乎表明string.Join
在很多次迭代中对小数组的效果优于StringBuilder
。您也应该对较大的阵列进行基准测试。正如我发布的那样,我看到BrokenGlass回答StringBuilder
在string.Join
内部使用,所以你可以预期它会更快。
答案 4 :(得分:1)
您的第二个解决方案最后会额外添加,
。看看Eric Lippert`s blog entry
我建议您修复第二个解决方案。一个StringBuilder肯定会更快,因为你避免将列表内容复制到一个新数组。
StringBuilder builder = new StringBuilder();
string separator = "";
stringList.ForEach(
val =>
{
builder.Append(separator).Append(val);
separator = ",";
});
string outcome = builder.ToString();
答案 5 :(得分:0)
StringBuilder是一种非常有效的方法,建议在这里使用。
答案 6 :(得分:0)
我尝试使用StrignBuilder的这个特殊实现比String.Join更快。 不仅仅是String.Join是一个MEMORY HOG。 我试用了20000000个字符串,当我的实现完成时,String.Join总是给OutOfMemory。 在你的机器上如果你的内存少于8Gb,它甚至可以在更少的字符串上。 评论其中一个要测试的实现。 除非您使用固定的string []数组,否则这是正确的。 String.Join在那里很好。
public static void Main(string[] Args)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
List<string> strings = new List<string>() {};
for (double d = 0; d < 8000000; d++) {
strings.Add(d.ToString());
}
TimeSpan upTime;
TimeSpan newupTime;
using (var pc = new PerformanceCounter("System", "System Up Time"))
{
StringBuilder sb = new StringBuilder(strings.Count);
int i;
pc.NextValue(); //The first call returns 0, so call this twice
upTime = TimeSpan.FromSeconds(pc.NextValue());
for (i = 0; i < strings.Count - 1; i++)
{
sb.Append(strings[i]);
sb.Append(",");
}
sb.Append(strings[i]);
newupTime = TimeSpan.FromSeconds(pc.NextValue());
sb = null;
Console.WriteLine("SB " + (newupTime - upTime).TotalMilliseconds);
}
using (var pc = new PerformanceCounter("System", "System Up Time"))
{
pc.NextValue();
upTime = TimeSpan.FromSeconds(pc.NextValue());
string s = string.Join(",", strings);
newupTime = TimeSpan.FromSeconds(pc.NextValue());
Console.WriteLine("JOIN " + (newupTime - upTime).TotalMilliseconds);
}
}
SB 406
JOIN 484
答案 7 :(得分:0)
根据以下测试,我在大型阵列上做了加速快了3倍:
Text.txt
文件包含38400行的值"aaaaaaaaaaaaaaaaaaa"
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var strings = File.ReadAllLines("Text.txt");
Stopwatch sw;
StringBuilder sb = new StringBuilder();
sw = Stopwatch.StartNew();
for (int i = 0; i < strings.Length; i++)
{
sb.AppendLine(strings[i]);
}
sw.Stop();
TimeSpan sbTime = sw.Elapsed;
sw = Stopwatch.StartNew();
var output = string.Join(",", strings);
sw.Stop();
TimeSpan joinTime = sw.Elapsed;
}
}
}
输出:
00:00:00.0098754
00:00:00.0032922
答案 8 :(得分:0)
String.Join是最快的。更深层次的原因是String.Join循环遍历数组并分配具有正确大小的最终字符串缓冲区,因为它在第一遍中添加所有字符串的字符串长度。当您使用StringBuilder及其容量时,您可以获得类似的结果。黄金法则是以两次循环数组为代价来节省内存分配。哪种方法更快取决于列表中有多少项以及resultint字符串的大小。
此致, Alois Kraus
答案 9 :(得分:0)
测试代码:
public static void Performance(Action fn)
{
var timer = new Stopwatch();
timer.Start();
for (var i = 0; i < 10000000; ++i)
{
fn();
}
timer.Stop();
Console.WriteLine("{0} Time: {1}ms ({2})", fn.ToString(), timer.ElapsedMilliseconds, timer.ElapsedTicks);
}
static void Main(string[] args)
{
var stringList = new List<string>() {
"123123123213",
"1232113213213",
"123213123"
};
string outcome = String.Empty;
Performance(() =>
{
outcome = string.Join(",", stringList);
});
Console.WriteLine(outcome);
Performance(() =>
{
StringBuilder builder = new StringBuilder();
stringList.ForEach
(
val =>
{
builder.Append(val);
builder.Append(",");
}
);
outcome = builder.ToString();
outcome = outcome.Substring(0, outcome.Length - 1);
});
Console.WriteLine(outcome);
Console.ReadKey();
}
结果1. String.Join
- 2. StringBuilder + SubString
。 ####ms (ticks)
在这种情况下,String.Join
速度更快,但如果您可以使用尾随,
,那么
StringBuilder
稍快一些(尾随,
)。
答案 10 :(得分:0)
如果一个人想要冷静并在重燃料上运行,请使用Aggregate
List<string> stringList = new List<string> { "1234567890", "34343434", "4343434" };
Console.WriteLine( stringList.Aggregate( ( current, next ) => string.Format( "{0}, {1}", current, next ) ) );
// Outputs: 1234567890, 34343434, 4343434