5

I have the following code:

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

Can I iterate over StringBuilder object using for, or foreach?

Can I display one element of it? For example Console.WriteLine(sb[0]); doesn't work.

7
  • 2
    It really sounds like a StringBuilder is the wrong object that you should be using, what are you trying to do? Commented Jul 1, 2015 at 10:43
  • 4
    This seems to be a classical XY problem, where X is your original problem and your perceived solution was "I know, I'll use StringBuilder", causing you to have the problem Y: "But now I can't get separate strings back from the StringBuilder". Explain your original problem X. Commented Jul 1, 2015 at 10:45
  • A possibility is to store each Append with a separator <space> (may be). and split with Split(separator) and show elements[0] where elements is the array of splits. Commented Jul 1, 2015 at 10:51
  • @NeverHopeless no, simply accept you have the wrong data structure for your problem. Don't go implement hacks like that. Commented Jul 1, 2015 at 10:53
  • 1
    @CodeCaster, It really depends on what OP is trying to achieve ? Code may break, but depends on the allowed input string. we can't decide here without going into details. You suggested List<> option but may be OP would like to stick with StringBuilder for no reason. One has the right to provide alternatives which may/may not be buggy for others. Commented Jul 1, 2015 at 11:11

6 Answers 6

4

You seem to be looking for a List<string>, to which you can Add() strings that you can later get by index (list[n]) and iterate over (foreach (string s in list)).

StringBuilder doesn't support this, as it concatenates all input internally and can't distinguish between values of different Append() calls afterwards.

To get a concatenated string from a list of strings, see Append List items to StringBuilder.

Sign up to request clarification or add additional context in comments.

Comments

3

StringBuilder doesn't implement IEnumerable, so you can't foreach over it, but you can do something like this:

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

2 Comments

if (Char.IsUpper(c)) Console.Write('\n'); ... no, no. This assumes that the input always starts with an uppercase character and doesn't contain any other uppercase characters. OP should use a different data structure or at least explain their problem properly.
@CodeCaster I know, but here OP is just adding names always starting with uppercase letters, so it just works in this case if OP insists on iterating a StringBuilder
1

StringBuilder is not a collection or array. It's just a class that provides some extra features to work with string. It doesn't implement IEnumerable interface.

sb.Append method just concatenates strings like you do if you type "text " + "some other text" but in a much better way in terms of efficiency. In fact every "s1" + "s2" results in creating of new string. If you want to do it like 1000 times so it creates new string again and again with a lot of extra operations to do. StringBuilder provides a way to avoid it, when it 'renders' string it updates the same string instead of creating new istance every time.

Comments

0

If you really want to stick with a StringBuilder you can use an extension method to give you a List and then you can access it with an element number.

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

You can then access it by calling the ToList() method.

int i = 0;
StringBuilder SB = new StringBuilder();
while (i++ != 1000000)
{
    SB.AppendLine(i.ToString());
}

string ChosenElement = SB.ToList()[1000];

2 Comments

This assumes the input strings never contain a newline. Use a StringBuilder to build strings, use a List<T> to store items you want to look up on index and that you want to iterate over.
@CodeCaster Yes it does but its the closest you can get without initially using a List.
0

I know its too late to answer this question, but i hope someone else get help from this.

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

EDIT: in your example:

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

2 Comments

its not too late- just write an explanation of what you did.
i just add a special character to the string at the end ~ 'sb.append();' and then split the string over that character. You can add your own token and then split the stringbuilder object with that token in foreach loop.
0

I was able to get a workable solution for a very similar scenario by using this post as a guideline:

Replace Line Breaks in a String C#

If you are able to use sb.AppendLine instead you could split the resulting ToString() via the newline characters '\r' and '\n'

// 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]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.