views:

173

answers:

2

Hi, i'm trying to build a function that will tell me the range of a string at an occurrence.

For example if I had the string "hello, hello, hello", I want to know the range of hello at it's, lets say, third occurrence.

I've tried building this simple function, but it doesn't work.

Note - the top functions were constructed at an earlier date and work fine.

Any help appreciated.

- (NSString *)stringByTrimmingString:(NSString *)stringToTrim toChar:(NSUInteger)toCharacterIndex {

   if (toCharacterIndex > [stringToTrim length]) return @"";

   NSString *devString = [[[NSString alloc] init] autorelease];

   for (int i = 0; i <= toCharacterIndex; i++) {

   devString = [NSString stringWithFormat:@"%@%@", devString, [NSString stringWithFormat:@"%c", [stringToTrim characterAtIndex:(i-1)]]]; 

   }

   return devString;

   [devString release];
   }

- (NSString *)stringByTrimmingString:(NSString *)stringToTrim fromChar:(NSUInteger)fromCharacterIndex {
   if (fromCharacterIndex > [stringToTrim length]) return @"";
   NSString *devString = [[[NSString alloc] init] autorelease];
   for (int i = (fromCharacterIndex+1); i <= [stringToTrim length]; i++) {
       devString = [NSString stringWithFormat:@"%@%@", devString, [NSString stringWithFormat:@"%c", [stringToTrim characterAtIndex:(i-1)]]]; 
   }
   return devString;
   [devString release];
}



- (NSRange)rangeOfString:(NSString *)substring inString:(NSString *)string atOccurence:(int)occurence {

   NSString *trimmedString = [inString copy]; //We start with the whole string.
   NSUInteger len, loc, oldLength;
   len = 0;
   loc = 0;


   NSRange tempRange = [string rangeOfString:substring];
   len = tempRange.length;
   loc = tempRange.location;

   for (int i = 0; i != occurence; i++) {

      NSUInteger endOfWord = len+loc;

      trimmedString = [self stringByTrimmingString:trimmedString fromChar:endOfWord];

      oldLength += [[self stringByTrimmingString:trimmedString toChar:endOfWord] length];

      NSRange tmp = [trimmedString rangeOfString:substring];
      len = tmp.length;
      loc = tmp.location + oldLength;

   }

   NSRange returnRange = NSMakeRange(loc, len);

   return returnRange;

}
+1  A: 

Instead of trimming the string a bunch of times (slow), just use rangeOfString:options:range:, which searches only within the range passed as its third argument. See Apple's documentation.

So try:

- (NSRange)rangeOfString:(NSString *)substring
                inString:(NSString *)string
             atOccurence:(int)occurence
{
  int currentOccurence = 0;
  NSRange rangeToSearchWithin = NSMakeRange(0, string.length);

  while (YES)
  {
    currentOccurence++;
    NSRange searchResult = [string rangeOfString: substring
                                         options: NULL
                                           range: rangeToSearchWithin];

    if (searchResult.location == NSNotFound)
    {
      return searchResult;
    }
    if (currentOccurence == occurence)
    {
      return searchResult;
    }

    int newLocationToStartAt = searchResult.location + searchResult.length;
    rangeToSearchWithin = NSMakeRange(newLocationToStartAt, string.length - newLocationToStartAt);
  }
}
Jon Rodriguez
Thanks for that :) I finally see what I'm doing wrong.
Jack Greenhill
+1  A: 

You need to rework the whole code. While it may seem to work, it's poor coding and plain wrong, like permanently reassigning the same variable, initializing but reassigning one line later, releasing after returning (which will never work).

For your question: Just use rangeOfString:options:range:, and do this the appropriate number of times while just incrementing the starting point.

Eiko