【问题标题】:Loop over strings added to StringBuilder循环添加到 StringBuilder 的字符串
【发布时间】:2015-09-18 11:25:27
【问题描述】:

我有以下代码:

StringBuilder sb = new StringBuilder();
sb.Append("Ola");
sb.Append("Jola");
sb.Append("Zosia");

我可以使用forforeach 迭代StringBuilder 对象吗?

我可以显示其中的一个元素吗?例如 Console.WriteLine(sb[0]); 不起作用。

【问题讨论】:

  • 听起来StringBuilder 是你应该使用的错误对象,你想做什么?
  • 这似乎是一个经典的 XY 问题,其中 X 是您的原始问题,而您认为的解决方案是 “我知道,我将使用 StringBuilder,导致您遇到问题 Y:“但现在我无法从 StringBuilder 获取单独的字符串”。解释你原来的问题 X。
  • 一种可能性是使用分隔符<space> 存储每个Append(可能是)。并使用 Split(separator) 拆分并显示 elements[0] 其中 elements 是拆分数组。
  • @NeverHopeless 不,只需接受您的问题的数据结构错误。不要去实施这样的黑客攻击。
  • @CodeCaster,这真的取决于 OP 想要实现什么?代码可能会中断,但取决于允许的输入字符串。如果不详细说明,我们无法在这里做出决定。您建议了 List<> 选项,但可能是 OP 想无缘无故地坚持使用 StringBuilder。一个人有权提供对他人可能/可能不会有问题的替代方案。

标签: c# stringbuilder


【解决方案1】:

您似乎正在寻找一个List<string>,您可以通过Add() 字符串获取该字符串,稍后您可以通过索引(list[n]) 获取并迭代(foreach (string s in list))。

StringBuilder 不支持这一点,因为它在内部连接所有输入,并且无法区分之后不同 Append() 调用的值。

要从字符串列表中获取连接的字符串,请参阅Append List items to StringBuilder

【讨论】:

    【解决方案2】:

    StringBuilder 不是集合或数组。它只是一个提供一些额外功能来处理字符串的类。它没有实现 IEnumerable 接口。

    sb.Append 方法只是连接字符串,就像您键入“文本”+“其他文本”时所做的那样,但在效率方面要好得多。事实上,每个 "s1" + "s2" 都会导致创建新字符串。如果你想这样做 1000 次,那么它会一次又一次地创建新字符串,并需要做很多额外的操作。 StringBuilder 提供了一种避免它的方法,当它“渲染”字符串时,它会更新相同的字符串,而不是每次都创建新的 istance。

    【讨论】:

      【解决方案3】:

      StringBuilder 没有实现IEnumerable,所以你不能foreach 覆盖它,但你可以这样做:

      StringBuilder sb = new StringBuilder();
      sb.Append("Ola");
      sb.Append("Jola");
      sb.Append("Zosia");
      
      for (int i = 0; i < sb.Length; i++)
      {
          char c = sb[i];
          if (Char.IsUpper(c)) Console.Write('\n');
          Console.Write(c);
      }
      

      【讨论】:

      • if (Char.IsUpper(c)) Console.Write('\n'); ...不,不。这假定输入始终以大写字符开头并且不包含任何其他大写字符。 OP 应该使用不同的数据结构或至少正确解释他们的问题。
      • @CodeCaster 我知道,但是这里 OP 只是添加总是以大写字母开头的名称,所以如果 OP 坚持迭代 StringBuilder
      【解决方案4】:

      如果您真的想坚持使用 StringBuilder,您可以使用扩展方法为您提供一个 List,然后您可以使用元素编号访问它。

      internal static class ExtensionMethods
      {
          public static List<string> ToList(this StringBuilder stringBuilder)
          {
              return stringBuilder.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.None).ToList();
          }
      }
      

      然后您可以通过调用 ToList() 方法来访问它。

      int i = 0;
      StringBuilder SB = new StringBuilder();
      while (i++ != 1000000)
      {
          SB.AppendLine(i.ToString());
      }
      
      string ChosenElement = SB.ToList()[1000];
      

      【讨论】:

      • 这假定输入字符串从不包含换行符。使用StringBuilder 来构建字符串,使用List&lt;T&gt; 来存储要在索引上查找和要迭代的项目。
      • @CodeCaster 是的,但它是最接近您无需最初使用列表即可获得的。
      【解决方案5】:

      我知道现在回答这个问题为时已晚,但我希望其他人能从中得到帮助。

       public static void Main(string[] args)
          {
      
              StringBuilder sb = new StringBuilder("1");
              for(int i=2; i<= 300; i++){
                      sb.Append(i+" this is test.~");
              }
              foreach(string s in sb.ToString().Split('~')){
              Console.WriteLine(s);
              }
          }
      

      编辑: 在你的例子中:

       StringBuilder sb = new StringBuilder();
           sb.Append("Ola~");
           sb.Append("Jola~");  
           sb.Append("Zosia~");
      
       //foreach loop ver sb object
      
        foreach(string s in sb.ToString().Split('~')){
               Console.WriteLine(s);
                }
      

      【讨论】:

      • 现在还不算太晚 - 只需写下你所做的解释即可。
      • 我只是在字符串末尾添加一个特殊字符 ~ 'sb.append();'然后将字符串拆分为该字符。您可以添加自己的令牌,然后在 foreach 循环中使用该令牌拆分 stringbuilder 对象。
      【解决方案6】:

      通过使用这篇文章作为指导,我能够为非常相似的场景找到一个可行的解决方案:

      Replace Line Breaks in a String C#

      如果您能够使用 sb.AppendLine 代替,您可以通过换行符 '\r' 和 '\n' 拆分生成的 ToString()

      // e.g whereas you had:
      StringBuilder sb = new StringBuilder();
      sb.Append("Ola");
      sb.Append("Jola");
      sb.Append("Zosia");
      
      // the scenario will only work if you did the following:
      StringBuilder sb = new StringBuilder();
      sb.AppendLine("Ola");
      sb.AppendLine("Jola");
      sb.AppendLine("Zosia");
      
      // you can split your strings as follows:
      string[] resultLines = TestResultStr.ToString().Split(new char[] { '\n', '\r' });
      
      for (int i = 0; i < resultLines.Length; i++)
      {
          Console.WriteLine(resultLines[i]);
      }
      

      【讨论】:

        猜你喜欢
        • 2021-09-04
        • 2014-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-31
        • 2022-11-30
        • 2019-02-03
        相关资源
        最近更新 更多