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
.
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 string
from that, which seems expensive.
I would've thought this would be common functionality built into the .NET framework somewhere. Is there a simpler way to do this?
For those interested, the reason I'd like to use this is to use LINQ to filter strings:
string allowedString = new string(inputString.Where(c => allowedChars.Contains(c)).ToArray());
You can use String.Concat()
.
var allowedString = String.Concat(
inputString.Where(c => allowedChars.Contains(c))
);
Caveat: This approach will have some performance implications. String.Concat
doesn'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.
I don't think there are any implementations within the framework that will special case char
so you'll have to implement it. A simple loop appending characters to a string builder is simple enough to create.
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:
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();
}