2

Please let me preface this question with an apology. I am very new to Objective C. Unfortunately, I have a very tight timeline on a project for work and need to get up to speed as fast as possible.

The code below works. I am just wondering if there is a better way to handle this... Maybe something more Cocoa-ish. The entire purpose of the function is to get an ordered list of positions in a string that have a certain value.

I fell back on a standard array for comfort reasons. The NSMutableString that I initially declare is only for testing purposes. Being a complete noob to this language and still wrapping my head around the way Objective C (and C++ I guess) handles variables and pointers, any and all hints, tips, pointers would be appreciated.

NSMutableString *mut = [[NSMutableString alloc] initWithString:@"This is a test of the emergency broadcast system.  This is only a test."];

NSMutableArray *tList = [NSMutableArray arrayWithArray:[mut componentsSeparatedByString:@" "]];

int dump[(tList.count-1)];
int dpCount=0;
NSUInteger length = [mut length];
NSRange myRange = NSMakeRange(0, length);

while (myRange.location != NSNotFound) {

    myRange = [mut rangeOfString:@" " options: 0 range:myRange];

    if (myRange.location != NSNotFound) {
        dump[dpCount]=myRange.location;
        ++dpCount;
        myRange = NSMakeRange((myRange.location+myRange.length), (length - (myRange.location+myRange.length)));
    }
}

for (int i=0; i < dpCount; ++i) {
    //Going to do something with these values in the future... they MUST be in order.
    NSLog(@"Dumping positions in order: %i",dump[i]);
}
text2.text = mut;
[mut release];

Thanks again for any replies.

Sagan
  • 45
  • 3
  • Sagan, in general, Stack Overflow isn't meant for providing code review or things like that. It's meant for questions that have a specific answer. Check out the [FAQ](http://stackoverflow.com/faq) for more info... That being said, in general, I think some guides would be useful to understand this kind of stuff. There are great books and online resources to help you out. I don't really see any major issues with your code at the moment, so there might not be anything to look out for. – Itai Ferber May 15 '12 at 23:20
  • Point taken... and apologies for the wasted question. It just seemed like I might be missing something obvious there. I'll try to post only my "Why doesn't this work!!!" questions in the future. Thanks again for your time. – Sagan May 15 '12 at 23:27
  • Can you explain more precisely what the function should do? You separate the words into `tList` but never use `tList`, then it seems you are just looping through the string trying to find all the locations of a space character? – dreamlax May 15 '12 at 23:39
  • First, there doesn't seem to be any good reason to use mutable strings and arrays here; you're just reducing performance and safety for no good reason if you don't want to ever change the contents. Second, as dreamlax suggests, it seems like your loop is calculating the exact same information that componentsSeparatedByString: already calculated for you. Once you've already called componentsSeparatedByString:, you can get the positions just by, e.g., adding up the lengths of all of the components. – abarnert May 16 '12 at 00:37
  • @dreamlax - The only reason I use tList is to get the size to initiate the dump array. – Sagan May 16 '12 at 00:44
  • @abarnert - Thanks for the comment. The string is mutable because it will be modified later. The array is mutable, because I forgot to change it back from an earlier attempt. Thanks for the length idea; that should have occurred to me. – Sagan May 16 '12 at 00:48

2 Answers2

1

There is not great way to do what you are trying to do. Here is one way:

// locations will be an NSArray of NSNumbers -- 
// each NSNumber containing one location of the substring):
NSMutableArray *locations = [NSMutableArray new];
NSRange searchRange = NSMakeRange(0,string.length);
NSRange foundRange;
while (searchRange.location < string.length) {
    searchRange.length = string.length-searchRange.location;
    foundRange = [string rangeOfString:substring options:nil range:searchRange];
    if(foundRange.location == NSNotFound) break;
    [locations addObject:[NSNumber numberWithInt:searchRange.location]];
    searchRange.location = foundRange.location+foundRange.length;
}
Michael Frederick
  • 16,664
  • 3
  • 43
  • 58
  • Thank you. The whole reason I went with a standard array was because I could not cram the location property into NSNumber for some reason... It kept giving me a pointer error. Your way worked and allowed me to enumerate it later. – Sagan May 16 '12 at 01:10
1

This might be a little more streamlined (and faster in terms of execution time, if that matters):

const char *p = "This is a test of the emergency broadcast system.  This is only a test.";
NSMutableArray *positions = [NSMutableArray array];

for (int i = 0; *p; p++, i++)
{
    if (*p == ' ') {
        [positions addObject:[NSNumber numberWithInt:i]];
    }
}

for (int j = 0; j < [positions count]; j++) {
    NSLog(@"position %d: %@", j + 1, [positions objectAtIndex:j]);
}
jlehr
  • 15,557
  • 5
  • 43
  • 45
  • The ternary operator is not necessary, what you're saying is "if `i` is 0 then put 0 in the array, otherwise if `i` is not 0 then put `i` in the array". – dreamlax May 16 '12 at 00:49
  • Thank you. Elegant looking solution. Looks like I might need to take a step back and take a crash course in C++ as well. – Sagan May 16 '12 at 01:31
  • @dreamlax - Doh! I tweaked the solution code before posting and forgot to remove it. Thanks, I'll update the answer. – jlehr May 16 '12 at 13:03
  • @Sagan - That's just plain old ANSI C. C++ is a separate language; you won't need to learn it to do Objective-C development. ANSI C however is part of the Objective-C language, so that you *do* want to pick up. – jlehr May 16 '12 at 13:09