IEnumerable<char> to string
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();
}
Edited for the release of .Net Core 2.1
Repeating the test for the release of .Net Core 2.1, I get results like this
1000000 iterations of "Concat" took 842ms.
1000000 iterations of "new String" took 1009ms.
1000000 iterations of "sb" took 902ms.
In short, if you are using .Net Core 2.1 or later, Concat
is king.
See MS blog post for more details.
I've made this the subject of another question but 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
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 1000000
iterations of "Some reasonably small test data"
I get results like this,
1000000 iterations of "Concat" took 1597ms.
1000000 iterations of "new string" took 869ms.
1000000 iterations of "StringBuilder" took 748ms.
This suggests to me that there is not good reason to use string.Concat
for this task. If you want simplicity use the new string approach and if want performance use the StringBuilder.
I would caveat my assertion, in practice all these methods work fine, and this could all be over optimization.
As of .NET 4, many string methods take IEnumerable as arguments.
string.Concat(myEnumerable);