IEnumerable <char> to string </char>

时间:2012-07-25 16:17:52

标签: c# .net string ienumerable

我以前从来没有偶然发现过这个问题,但我现在感到很惊讶,我找不到将IEnumerable<char>转换为string的简单方法。

我能想到的最好的方法是string str = new string(myEnumerable.ToArray());,但是,对我来说,似乎这会创建一个新的char[],然后从中创建一个新的string,看起来很贵。

我认为这将是.NET框架内置的常用功能。有更简单的方法吗?

对于那些感兴趣的人,我想使用它的原因是使用LINQ来过滤字符串:

string allowedString = new string(inputString.Where(c => allowedChars.Contains(c)).ToArray());

6 个答案:

答案 0 :(得分:129)

您可以使用String.Concat()

var allowedString = String.Concat(
    inputString.Where(c => allowedChars.Contains(c))
);

警告:这种方法会产生一些性能影响。 String.Concat不是字符的特殊情况集合,因此它的表现就好像每个字符都转换为字符串,然后按照in the documentation and it actually does )连接起来。当然,这为您提供了完成此任务的内置方法,但可以做得更好。

我认为框架中没有任何特殊情况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();
}

答案 1 :(得分:71)

编辑发布.Net Core 2.1

重复测试.Net Core 2.1的发布,我得到了这样的结果

  

“Concat”的1000000次迭代耗时842ms。

     

1000000次“new String”迭代耗时1009ms。

     

“sb”的1000000次迭代耗时902ms。

简而言之,如果您使用.Net Core 2.1或更高版本,则Concat为王。

有关详细信息,请参阅MS blog post


我已将此作为another question的主题,但越来越多,这正在成为这个问题的直接答案。

我已经对3种将IEnumerable<char>转换为string的简单方法进行了一些性能测试,这些方法是

  

新字符串

return new string(charSequence.ToArray());
  

<强>的毗连

return string.Concat(charSequence)
  

<强>的StringBuilder

var sb = new StringBuilder();
foreach (var c in charSequence)
{
    sb.Append(c);
}

return sb.ToString();

在我的测试中,详细信息在linked question中,针对1000000的{​​{1}}次迭代,我得到了这样的结果,

  

“Concat”的1000000次迭代耗时1597ms。

     

“新字符串”的1000000次迭代耗时869ms。

     

“StringBuilder”的1000000次迭代耗时748ms。

这告诉我,没有充分的理由使用"Some reasonably small test data"来执行此任务。如果您想要简单,请使用 new string 方法,如果想要性能,请使用 StringBuilder

我会告诫我的断言,在实践中所有这些方法都运行良好,这可能都是过度优化。

答案 2 :(得分:17)

从.NET 4开始,许多字符串方法将IEnumerable视为参数。

string.Concat(myEnumerable);

答案 3 :(得分: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();
}

我的结果

。通过

  • STRLEN = 31
  • ITERATIONS = 1000000

<强>输入

  • ((IEnumerable<char>)RandomString(STRLEN)).Reverse()

<强>结果

  • Concat:1x
  • 新:3x
  • StringBuilder:3x

<强>输入

  • ((IEnumerable<char>)RandomString(STRLEN)).Take((int)ITERATIONS/2)

<强>结果

  • Concat:1x
  • 新:7x
  • StringBuilder:7x

<强>输入

  • ((IEnumerable<char>)RandomString(STRLEN)) (这只是一个向上)

<强>结果

  • Concat:0 ms
  • 新:2000毫秒
  • StringBuilder:2000 ms
  • Downcast:0 ms

我在面向.NET Framework 3.5的Intel i5 760上运行此功能。

答案 4 :(得分:10)

另一种可能性是使用

string.Join("", myEnumerable);

我没有衡量表现。

答案 5 :(得分:9)

以下是StringBuilder答案的更简洁版本:

return charSequence.Aggregate(new StringBuilder(), (seed, c) => seed.Append(c)).ToString();

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

所以,如果你是累积者的粉丝,那么你就去吧。