2

I'd like to find a specific last character in a StringBuilder.
I know, I can solve it with while() but is there an build it option to do that easily?

eg:

private static StringBuilder mySb = new StringBuilder("");
mySb.Add("This is a test[n] I like Orange juice[n] Can you give me some?");

Now: It shoud find the ] and give me the possition. Like: 40

Thanks in advance

ruffin
  • 16,507
  • 9
  • 88
  • 138
Smilla J.
  • 1,124
  • 10
  • 15
  • possible duplicate, have you checked this http://stackoverflow.com/questions/12261344/fastest-search-method-in-stringbuilder ? – st4hoo May 13 '14 at 08:54
  • Let me be clear. Do you need to get the last index of `]` ?? Please have a look [StringBuilder Extensions](http://www.codeproject.com/Tips/129369/StringBuilder-Extensions) you will find everything you need!! – huMpty duMpty May 13 '14 at 08:54
  • You could call `ToString` on the `StringBuilder` and then use `LastIndexOf` on that `string`... – germi May 13 '14 at 08:56
  • fyi, the index would be 39 since its 0 indexed. – Sayse May 13 '14 at 08:57
  • 1
    Why can't you check the string _before_ appending it to the stringbuilder? – CodeCaster May 13 '14 at 09:23

2 Answers2

5

Since there is no builtin method and always creating a string from the StringBuilder via ToString can be quite inefficient you could create an extension method for this purpose:

public static int LastIndexOf(this StringBuilder sb, char find, bool ignoreCase = false, int startIndex = -1, CultureInfo culture = null)
{
    if (sb == null) throw new ArgumentNullException(nameof(sb));
    if (startIndex == -1) startIndex = sb.Length - 1;
    if (startIndex < 0 || startIndex >= sb.Length) throw new ArgumentException("startIndex must be between 0 and sb.Lengh-1", nameof(sb));
    if (culture == null) culture = CultureInfo.InvariantCulture;

    int lastIndex = -1;
    if (ignoreCase) find = Char.ToUpper(find, culture);
    for (int i = startIndex; i >= 0; i--)
    {
        char c = ignoreCase ? Char.ToUpper(sb[i], culture) : (sb[i]);
        if (find == c)
        {
            lastIndex = i;
            break;
        }
    }
    return lastIndex;
}

Add it to a static, accessible (extension) class, then you can use it in this way:

StringBuilder mySb = new StringBuilder("");
mySb.Append("This is a test[n] I like Orange juice[n] Can you give me some?");
int lastIndex = mySb.LastIndexOf(']');  // 39
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • 1
    Always using the current culture for the case insensitive comparison might not be a good idea. Turkish `i` vs `ı` etc. – CodesInChaos May 13 '14 at 09:33
  • @CodesInChaos: i have edited my answer, have a look. I think it's sufficient to use a `bool` as parameter when comparing chars, isn't it? – Tim Schmelter May 13 '14 at 09:37
  • I generally prefer passing in a `CultureInfo` or simply using the invariant culture everywhere, but locale aware string functions are a mess in .net. No idea why they used the current local by default. – CodesInChaos May 13 '14 at 09:41
-3

Convert the StringBuilder to a string with the toString method, thereafter you can make use of the LastIndexOf method.

mySb.ToString().LastIndexOf(']');

LastIndexOf:

Reports the zero-based index position of the last occurrence of a specified Unicode character or string within this instance. The method returns -1 if the character or string is not found in this instance.

This member is overloaded. For complete information about this member, including syntax, usage, and examples, click a name in the overload list.

bobthedeveloper
  • 3,733
  • 2
  • 15
  • 31
  • Yes, you can. But if you'll do this in a loop you will always create a new string from the complete `StringBuilder` just to find an index. This can be quite inefficient. I would suggest to create methods/extensions that use a loop on the `StringBuilder` itself. – Tim Schmelter May 13 '14 at 09:08