HowTo: Add startIndex to String.IndexOf(string)?

Started by Lt. Smash, Sun 10/08/2008 19:15:40

Previous topic - Next topic

Lt. Smash

Hey all!

I wanted to make a custom Split() function for Strings* but I found out that I can not set a starting index to IndexOf/Contains.

The code for the split function is here:
Code: ags

void Split(this String*, String separator, String array[])
{
	int n = this.Length;
	int start, stop, i;
	while (start >= 0 && start < n) 
	{
		stop = this.IndexOf(separator, start); //the second parameter is the startingIndex (from that index the function searches)
		if (stop < 0 || stop > n) stop = n;
		array[i] = this.Substring(start, stop);
		start = this.IndexOf(separator, stop+1);
		i++;
	}
}

So I want to ask you if you could help me coding an overloaded version of indexOf.
It would be even better if CJ could add an overloaded version to the next ags version. (Maybe also an String.split(String separator, String array[]?)

scotch

Could use

Code: ags
int IndexOf(this String*, String sub, int start) {
    if(start>=this.Length-sub.Length) return -1;
    if(start<=0) return this.Contains(sub);
    String e = this.Substring(start, this.Length-start);
    int i = e.Contains(sub);
    if(i>=0) i += start;
    return i;
}


watch out in your Split function though, there are some bugs

Code: ags
int Split(this String*, String separator, String array[]) {
    int n = this.Length;
    int start, stop, i;
    while(start >= 0 && start < n) {
      stop = this.IndexOf(separator, start);
      if(stop < 0 || stop > n) stop = n;
      if(stop>start) {
         array[i] = this.Substring(start, stop-start);
         i++;
      }
      start = stop+separator.Length;
    }
    return i;
}


might be ok.

Lt. Smash

Quote from: scotch on Sun 10/08/2008 20:26:39
Could use...
I just had to modify the function name because ags says its already defined
but now it works perfect. :)

thank you.

Pumaman

I keep meaning to add a String.Split method, but to do that I first need to add a .Length property to dynamic arrays. Some day... ;)

monkey0506

#4
Actually I would find the function more useful if there were some type of SplitStringType defined:

Code: ags
enum SplitStringType {
  eSplitStringByWidth, // would read the "separator" parameter as an int to split the string into X-length segments (perhaps this would just be better as an alternate function)
  eSplitStringByString, // would split the string based on occurrences of the separator parameter
  eSplitStringByDelimiter // would split the string based on occurrences of ANY of the characters in the separator parameter
};


Of course as noted, the "by width" functionality may be better suited to a separate function due to the int parameter. Then the Split function might only require some bool parameter like useWholeString to match the whole string or just any of the characters in the separator parameter.

And a Length property for dynamic arrays would be nice...but wouldn't it be so much easier just to allow dynamic arrays within structs in which case we could just as easily track it ourselves? :=

Some day... ;)

By the way, I guess you're pre-allocating the array? I've written a similar function before that allocates the array dynamically and returns the new array, using the first index to store the size, but it's probably slower since I have to loop over the text twice using the Contains/IndexOf function. Maybe a String.CountOf(String) function would be useful (coding a custom one would just do the same thing, looping through Contains again; not sure if this could be internally optimized).

SMF spam blocked by CleanTalk