Con*_*ell 136 .net c# string ienumerable
我以前从来没有偶然发现过这个问题,但我现在已经感到惊讶,因为我找不到一个非常简单的方法来转换IEnumerable<char>为a string.
我能想到的最好的方法是string str = new string(myEnumerable.ToArray());,但是,对我来说,似乎这会创造一个新的char[],然后string从中创造一个新的,这看起来很昂贵.
我认为这将是.NET框架内置的常用功能.有更简单的方法吗?
对于那些感兴趣的人,我想使用它的原因是使用LINQ来过滤字符串:
string allowedString = new string(inputString.Where(c => allowedChars.Contains(c)).ToArray());
Run Code Online (Sandbox Code Playgroud)
Jef*_*ado 142
你可以用String.Concat().
var allowedString = String.Concat(
inputString.Where(c => allowedChars.Contains(c))
);
Run Code Online (Sandbox Code Playgroud)
警告:这种方法会产生一些性能影响. String.Concat不是字符的特殊情况集合,所以它执行就好像每个字符都被转换为字符串然后连接文档中提到的(实际上它).当然,这为您提供了完成此任务的内置方法,但它可以做得更好.
我不认为框架内有任何特殊情况的char实现,所以你必须实现它.将字符附加到字符串构建器的简单循环非常简单,可以创建.
这是我在开发机器上采用的一些基准测试,看起来是正确的.
在32位版本构建上的300字符序列上进行1000000次迭代:
ToArrayString: 00:00:03.1695463 Concat: 00:00:07.2518054 StringBuilderChars: 00:00:03.1335455 StringBuilderStrings: 00:00:06.4618266
static readonly IEnumerable<char> seq = Enumerable.Repeat('a', 300);
static string ToArrayString(IEnumerable<char> charSequence)
{
return new String(charSequence.ToArray());
}
static string Concat(IEnumerable<char> charSequence)
{
return String.Concat(charSequence);
}
static string StringBuilderChars(IEnumerable<char> charSequence)
{
var sb = new StringBuilder();
foreach (var c in charSequence)
{
sb.Append(c);
}
return sb.ToString();
}
static string StringBuilderStrings(IEnumerable<char> charSequence)
{
var sb = new StringBuilder();
foreach (var c in charSequence)
{
sb.Append(c.ToString());
}
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
Jod*_*ell 79
编辑发布.Net Core 2.1
重复测试.Net Core 2.1的发布,我得到这样的结果
"Concat"的1000000次迭代耗时842ms.
"新字符串"的1000000次迭代耗时1009ms.
"sb"的1000000次迭代耗时902ms.
简而言之,如果您使用.Net Core 2.1或更高版本,Concat则为王.
有关详细信息,请参阅MS博客文章.
我已将此作为另一个问题的主题,但越来越多,这正在成为这个问题的直接答案.
我已经做了一些性能测试,将3种简单的方法转换IEnumerable<char>为a string,这些方法都是
新字符串
return new string(charSequence.ToArray());
Run Code Online (Sandbox Code Playgroud)
CONCAT
return string.Concat(charSequence)
Run Code Online (Sandbox Code Playgroud)
StringBuilder的
var sb = new StringBuilder();
foreach (var c in charSequence)
{
sb.Append(c);
}
return sb.ToString();
Run Code Online (Sandbox Code Playgroud)
在我的测试中,在链接问题中有详细说明,对于1000000迭代,"Some reasonably small test data"我得到这样的结果,
"Concat"的1000000次迭代耗时1597ms.
"新字符串"的1000000次迭代耗时869ms.
"StringBuilder"的1000000次迭代耗时748ms.
这告诉我,没有充分的理由使用string.Concat这项任务.如果你想要简单,请使用新的字符串方法,如果想要性能,请使用StringBuilder.
我会告诫我的断言,在实践中所有这些方法都运行良好,这可能都是过度优化.
Mik*_*keP 21
从.NET 4开始,许多字符串方法将IEnumerable作为参数.
string.Concat(myEnumerable);
Run Code Online (Sandbox Code Playgroud)
hBG*_*BGl 10
我的数据与Jodrell发布的结果相反.首先来看看我使用的扩展方法:
public static string AsStringConcat(this IEnumerable<char> characters)
{
return String.Concat(characters);
}
public static string AsStringNew(this IEnumerable<char> characters)
{
return new String(characters.ToArray());
}
public static string AsStringSb(this IEnumerable<char> characters)
{
StringBuilder sb = new StringBuilder();
foreach (char c in characters)
{
sb.Append(c);
}
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
同
输入
((IEnumerable<char>)RandomString(STRLEN)).Reverse()结果
输入
((IEnumerable<char>)RandomString(STRLEN)).Take((int)ITERATIONS/2)结果
输入
((IEnumerable<char>)RandomString(STRLEN)) (这只是一个向上)结果
我是在针对.NET Framework 3.5的Intel i5 760上运行的.
nit*_*ycs 10
另一种可能性是使用
string.Join("", myEnumerable);
Run Code Online (Sandbox Code Playgroud)
我没有衡量表现.
这是一个更简洁的StringBuilder版本的答案:
return charSequence.Aggregate(new StringBuilder(), (seed, c) => seed.Append(c)).ToString();
Run Code Online (Sandbox Code Playgroud)
我使用Jeff Mercado使用的相同测试进行计时,在相同的300字符序列(32位版本构建)上,1,000,000次迭代的速度比显式更慢1秒:
static string StringBuilderChars(IEnumerable<char> charSequence)
{
var sb = new StringBuilder();
foreach (var c in charSequence)
{
sb.Append(c);
}
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
所以,如果你是累积器的粉丝那么你去吧.
| 归档时间: |
|
| 查看次数: |
72762 次 |
| 最近记录: |