C# IEnumerable<char> 到字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11654190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IEnumerable<char> to string
提问by Connell
I've never stumbled across this before, but I have now and am surprised that I can't find a really easy way to convert an IEnumerable<char>to a string.
我以前从未遇到过这个问题,但现在我很惊讶我找不到一种非常简单的方法将 an 转换IEnumerable<char>为string.
The best way I can think of is string str = new string(myEnumerable.ToArray());, but, to me, it seems like this would create a new char[], and then create a new stringfrom that, which seems expensive.
我能想到的最好方法是string str = new string(myEnumerable.ToArray());,但是,对我来说,这似乎会创建一个新的char[],然后string从中创建一个新的,这似乎很昂贵。
I would've thought this would be common functionality built into the .NET framework somewhere. Is there a simpler way to do this?
我原以为这将是 .NET 框架中内置的通用功能。有没有更简单的方法来做到这一点?
For those interested, the reason I'd like to use this is to use LINQ to filter strings:
对于那些感兴趣的人,我想使用它的原因是使用 LINQ 来过滤字符串:
string allowedString = new string(inputString.Where(c => allowedChars.Contains(c)).ToArray());
采纳答案by Jeff Mercado
You can use String.Concat().
您可以使用String.Concat().
var allowedString = String.Concat(
inputString.Where(c => allowedChars.Contains(c))
);
Caveat: This approach will have some performance implications. String.Concatdoesn't special case collections of characters so it performs as if every character was converted to a string then concatenated as mentioned in the documentation(and it actually does). Sure this gives you a builtin way to accomplish this task, but it could be done better.
警告:这种方法会对性能产生一些影响。 String.Concat没有特殊情况的字符集合,所以它的表现就好像每个字符都被转换为一个字符串,然后按照文档中提到的那样连接起来(实际上确实如此)。当然,这为您提供了完成此任务的内置方法,但可以做得更好。
I don't think there are any implementations within the framework that will special case charso you'll have to implement it. A simple loop appending characters to a string builder is simple enough to create.
我认为框架内没有任何特殊情况的char实现,因此您必须实现它。将字符附加到字符串生成器的简单循环很容易创建。
Here's some benchmarks I took on a dev machine and it looks about right.
这是我在开发机器上进行的一些基准测试,看起来差不多。
1000000 iterations on a 300 character sequence on a 32-bit release build:
在 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();
}
回答by MikeP
As of .NET 4, many string methods take IEnumerable as arguments.
从 .NET 4 开始,许多字符串方法将 IEnumerable 作为参数。
string.Concat(myEnumerable);
回答by Jodrell
Edited for the release of .Net Core 2.1
为 .Net Core 2.1 的发布而编辑
Repeating the test for the release of .Net Core 2.1, I get results like this
重复测试 .Net Core 2.1 的发布,我得到这样的结果
1000000 iterations of "Concat" took 842ms.
1000000 iterations of "new String" took 1009ms.
1000000 iterations of "sb" took 902ms.
“Concat”的 1000000 次迭代需要 842 毫秒。
“新字符串”的 1000000 次迭代需要 1009 毫秒。
“sb”的 1000000 次迭代需要 902 毫秒。
In short, if you are using .Net Core 2.1 or later, Concatis king.
简而言之,如果您使用的是 .Net Core 2.1 或更高版本,Concat则为王。
See MS blog postfor more details.
有关更多详细信息,请参阅MS 博客文章。
I've made this the subject of another questionbut more and more, that is becoming a direct answer to this question.
我已将此作为另一个问题的主题,但越来越多地成为对这个问题的直接回答。
I've done some performance testing of 3 simple methods of converting an IEnumerable<char>to a string, those methods are
我已经对 3 种将 an 转换IEnumerable<char>为 a 的简单方法进行了一些性能测试string,这些方法是
new string
新字符串
return new string(charSequence.ToArray());
Concat
康卡特
return string.Concat(charSequence)
StringBuilder
字符串生成器
var sb = new StringBuilder();
foreach (var c in charSequence)
{
sb.Append(c);
}
return sb.ToString();
In my testing, that is detailed in the linked question, for 1000000iterations of "Some reasonably small test data"I get results like this,
在我的测试中,在链接问题中有详细说明,对于我的1000000迭代,"Some reasonably small test data"我得到这样的结果,
1000000 iterations of "Concat" took 1597ms.
1000000 iterations of "new string" took 869ms.
1000000 iterations of "StringBuilder" took 748ms.
“Concat”的 1000000 次迭代需要 1597 毫秒。
“新字符串”的 1000000 次迭代需要 869 毫秒。
“StringBuilder”的 1000000 次迭代需要 748 毫秒。
This suggests to me that there is not good reason to use string.Concatfor this task. If you want simplicity use the new stringapproach and if want performance use the StringBuilder.
这向我表明没有充分的理由使用string.Concat此任务。如果你想要简单使用新的字符串方法,如果想要性能使用StringBuilder。
I would caveat my assertion, in practice all these methods work fine, and this could all be over optimization.
我会警告我的断言,在实践中所有这些方法都可以正常工作,这可能都过度优化了。
回答by hBGl
My data is contrary to the results Jodrell posted. First have a look at the extension methods I use:
我的数据与 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();
}
My results
我的结果
With
和
- STRLEN = 31
- ITERATIONS = 1000000
- 斯特林 = 31
- 迭代次数 = 1000000
Input
输入
((IEnumerable<char>)RandomString(STRLEN)).Reverse()
((IEnumerable<char>)RandomString(STRLEN)).Reverse()
Results
结果
- Concat: 1x
- New: 3x
- StringBuilder: 3x
- 连接:1x
- 新:3倍
- 字符串生成器:3x
Input
输入
((IEnumerable<char>)RandomString(STRLEN)).Take((int)ITERATIONS/2)
((IEnumerable<char>)RandomString(STRLEN)).Take((int)ITERATIONS/2)
Results
结果
- Concat: 1x
- New: 7x
- StringBuilder: 7x
- 连接:1x
- 新:7x
- 字符串生成器:7x
Input
输入
((IEnumerable<char>)RandomString(STRLEN))(this is just an upcast)
((IEnumerable<char>)RandomString(STRLEN))(这只是一个upcast)
Results
结果
- Concat: 0 ms
- New: 2000 ms
- StringBuilder: 2000 ms
- Downcast: 0 ms
- 连接:0 毫秒
- 新:2000 毫秒
- 字符串生成器:2000 毫秒
- 向下转换:0 毫秒
I ran this on an Intel i5 760 targeting .NET Framework 3.5.
我在面向 .NET Framework 3.5 的 Intel i5 760 上运行它。
回答by nitrogenycs
Another possibility is using
另一种可能性是使用
string.Join("", myEnumerable);
I did not measure the performance.
我没有测量性能。
回答by Adam Smith
Here is a more succinct version of the StringBuilder answer:
这是 StringBuilder 答案的更简洁版本:
return charSequence.Aggregate(new StringBuilder(), (seed, c) => seed.Append(c)).ToString();
I timed this using the same tests that Jeff Mercado used and this was 1 second slower across 1,000,000 iterations on the same 300 character sequence (32-bit release build) than the more explicit:
我使用 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();
}
So if you're a fan of accumulators then here you go.
因此,如果您是蓄能器的粉丝,那么就来这里吧。

