IEnumerable<char> to string

Connell picture Connell · Jul 25, 2012 · Viewed 84.4k times · Source

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());

Answer

Jeff Mercado picture Jeff Mercado · Jul 25, 2012

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();
}