Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Dav-id

macrumors newbie
Original poster
Sep 1, 2008
3
0
I am pretty new to Objective-c but have been using Java and C# for a while so please bear with me if what I am asking is quite obvious.

In c# there is a method for strings where it is possible to get the index for a given character:

int index = myString.IndexOf(':');

I ideally would prefer not to loop through each character to find this index but I suppose as a last resort I may do so.

Any advice?

Thanks
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
As with most basic questions the answer is in the documentation.

As a favour I'll give you step by step instructions on how to use the documentation:

Open the NSString documentation

Scroll down till you find the method you need. In this case something from the section "Finding Characters and Substrings" is probably what you want.
 

Dav-id

macrumors newbie
Original poster
Sep 1, 2008
3
0
I think possibly I was expecting something that was more of a direct equivalent to within Java/C# but I understand now that I should be looking at something more like the following method

- (NSRange)rangeOfString:(NSString *)aString

Thanks
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
robbieduncan pointed you towards what you need to do exactly what you requested, but you may want to consider a different tact for your problem.

Why do you need to find the index of a character? Are you just splitting on it? Do you just want to see if a character is present? There are a lot of things NSString supports, and one of them may be a better fit than just finding the first occurrence of a character.

Also, some of this might be helpful while you're working with the NSString methods, though they are linked in most cases:
http://developer.apple.com/document...racterSet/characterSetWithCharactersInString:

http://developer.apple.com/document.../reference.html#//apple_ref/doc/c_ref/NSRange

-Lee
 

Dav-id

macrumors newbie
Original poster
Sep 1, 2008
3
0
I was looking to get the length of a substring without actually breaking the string.

NSRange appears to have provided me with the solution I was looking for.
 

Sayer

macrumors 6502a
Jan 4, 2002
981
0
Austin, TX
Yeah its simple once you know how:

Code:
	// tmityok: This will allow us to open specific URIs in Safari instead of WebNode
	
	NSMutableString *subs =  [NSMutableString stringWithString:[[request URL] absoluteString]];

	// scan for openInSafari, with or without value, remove from URL and launch Safari
	NSRange toprange = [subs rangeOfString: @"openInSafari"];
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
Not that anyone asked, but this also seemed like a case that you could extend NSString to provide extra functionality.

I then found out that actually extending NSString is a really bad idea (but not until I had done so and had this working), so I made a class using composition instead.

Using NS for your own classes isn't a good idea, I was just playing with this.

The result:

NSExtendedString.m:
Code:
#import "NSExtendedString.h"

@implementation NSExtendedString

-(unsigned int) indexOf:(char) searchChar {
  NSRange searchRange;
  searchRange.location=(unsigned int)searchChar;
  searchRange.length=1;
  NSRange foundRange = [backingString rangeOfCharacterFromSet:[NSCharacterSet characterSetWithRange:searchRange]];
  return foundRange.location;
}

-(NSExtendedString *) initWithString: (NSString *) origString {
  if(self = [super init]) {
    backingString = [[NSString alloc] initWithString:origString];
  }
  return self;
}
-(NSExtendedString *) initWithExtendedString: (NSExtendedString *) origString {
  if(self = [super init]) {
    backingString = [[origString string] copy];
  }
  return self;
}

-(NSString *) string {
  return backingString;
}
@end

NSExtendedString.h:
Code:
#import <Foundation/Foundation.h>

@interface NSExtendedString : NSObject {
  NSString *backingString;
}
- (unsigned int) indexOf:(char) searchChar;
-(NSExtendedString *) initWithString: (NSString *) origString;
-(NSExtendedString *) initWithExtendedString: (NSExtendedString *) origString;
-(NSString *) string;


@end

TestNewString.m:
Code:
#import <Foundation/Foundation.h>
#import "NSExtendedString.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSExtendedString *myString = [[NSExtendedString alloc] initWithString:@"Test:string+number-one"];
	unsigned int colonPosition = [myString indexOf:':'];
	unsigned int plusPosition = [myString indexOf:'+'];
	unsigned int minusPosition = [myString indexOf:'-'];
	NSLog(@"The position of the first colon is: %u, the position of the first plus is: %u, the position of the first minus is: %u",colonPosition,plusPosition,minusPosition);
	NSExtendedString *stringTwo = [[NSExtendedString alloc] initWithExtendedString:myString];
	unsigned int plusPositionTwo = [stringTwo indexOf:'+'];
	NSLog(@"Testing copy: %u",plusPositionTwo);
    [pool release];
    return 0;
}

I'm on 10.4, so the proper type for most everything in 10.5 and above would be NSUInteger rather than unsigned int.

-Lee
 

Door

macrumors newbie
Dec 27, 2010
1
0
Or just use the regex library

Having spent painful hours in many programming languages trying to use the native string parsing functionality, I've found that if you're doing any serious parsing of strings it's best just to go the regular expression route. I've not done much with the Objective C regex library yet but I'm starting to and it will definitely solve the problem specified in this thread.
Here's the class reference link:

http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html

I would be interested in knowing though whether on these smaller devices use of the regex library would hog significantly more memory. I suppose I can run the tools ...
 

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
Not that anyone asked, but this also seemed like a case that you could extend NSString to provide extra functionality.

I then found out that actually extending NSString is a really bad idea (but not until I had done so and had this working), so I made a class using composition instead.

Using NS for your own classes isn't a good idea, I was just playing with this.

The result:

NSExtendedString.m:
Code:
#import "NSExtendedString.h"

@implementation NSExtendedString

-(unsigned int) indexOf:(char) searchChar {
  NSRange searchRange;
  searchRange.location=(unsigned int)searchChar;
  searchRange.length=1;
  NSRange foundRange = [backingString rangeOfCharacterFromSet:[NSCharacterSet characterSetWithRange:searchRange]];
  return foundRange.location;
}

-(NSExtendedString *) initWithString: (NSString *) origString {
  if(self = [super init]) {
    backingString = [[NSString alloc] initWithString:origString];
  }
  return self;
}
-(NSExtendedString *) initWithExtendedString: (NSExtendedString *) origString {
  if(self = [super init]) {
    backingString = [[origString string] copy];
  }
  return self;
}

-(NSString *) string {
  return backingString;
}
@end

NSExtendedString.h:
Code:
#import <Foundation/Foundation.h>

@interface NSExtendedString : NSObject {
  NSString *backingString;
}
- (unsigned int) indexOf:(char) searchChar;
-(NSExtendedString *) initWithString: (NSString *) origString;
-(NSExtendedString *) initWithExtendedString: (NSExtendedString *) origString;
-(NSString *) string;


@end

TestNewString.m:
Code:
#import <Foundation/Foundation.h>
#import "NSExtendedString.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSExtendedString *myString = [[NSExtendedString alloc] initWithString:@"Test:string+number-one"];
	unsigned int colonPosition = [myString indexOf:':'];
	unsigned int plusPosition = [myString indexOf:'+'];
	unsigned int minusPosition = [myString indexOf:'-'];
	NSLog(@"The position of the first colon is: %u, the position of the first plus is: %u, the position of the first minus is: %u",colonPosition,plusPosition,minusPosition);
	NSExtendedString *stringTwo = [[NSExtendedString alloc] initWithExtendedString:myString];
	unsigned int plusPositionTwo = [stringTwo indexOf:'+'];
	NSLog(@"Testing copy: %u",plusPositionTwo);
    [pool release];
    return 0;
}

I'm on 10.4, so the proper type for most everything in 10.5 and above would be NSUInteger rather than unsigned int.

-Lee

To be fair, not that anyone asked, I don't really see the reason to extend NSString at all in this case to provide this functionality. Well not by subclassing anyway since Objective-C has such a nice way of giving existing classes new methods.

Code:
@interface NSString (indexOfChar)
- (unsigned int) indexOfChar: (char) toFind;
@end

@implementation NSString (indexOfChar)
// will return NSNotFound if not in the string
- (unsigned int) indexOfChar: (char) toFind {
     // you could experiment with this, I suspect linear searching each 
     // character would be about as fast as it can get.
     NSString *substring = [NSString stringWithFormat: @"%c", toFind];
     NSRange range = [self rangeOfString: substring];
     return range.location;
}
@end

// call like...
NSString *s = @"some string";
unsigned int index = [s indexOfChar: 'm'];
if (index != NSNotFound) {
...
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
To be fair, not that anyone asked, I don't really see the reason to extend NSString at all in this case to provide this functionality. Well not by subclassing anyway since Objective-C has such a nice way of giving existing classes new methods.

Code:
@interface NSString (indexOfChar)
- (unsigned int) indexOfChar: (char) toFind;
@end

@implementation NSString (indexOfChar)
// will return NSNotFound if not in the string
- (unsigned int) indexOfChar: (char) toFind {
     // you could experiment with this, I suspect linear searching each 
     // character would be about as fast as it can get.
     NSString *substring = [NSString stringWithFormat: @"%c", toFind];
     NSRange range = [self rangeOfString: substring];
     return range.location;
}
@end

// call like...
NSString *s = @"some string";
unsigned int index = [s indexOfChar: 'm'];
if (index != NSNotFound) {
...

To be fair (to me) I wrote that in 2008. I was embarrassed to see that not-category business when I looked at this thread, but feel better that it was so old (if you're not getting better...).

-Lee
 

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
To be fair (to me) I wrote that in 2008. I was embarrassed to see that not-category business when I looked at this thread, but feel better that it was so old (if you're not getting better...).

-Lee

Ha, I rarely notice the dates on old resurrected threads.

In 2008 I didn't know anything about programming and was merely an Apple Genius fixing broken computers.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.