How to check the last char of an NSString

Objective CCocoaNsstring

Objective C Problem Overview


I want to ask a question about the NSString * in objective C. Can I check the last char of a NSString * object?

Example:

NSString* data = @"abcde,";

if(data is end with ',') // I don't know this part
  // do sth

Objective C Solutions


Solution 1 - Objective C

NSString *data = @"abcde,";
if([data hasSuffix:@","]) // This returns true in this example
    // do something

Solution 2 - Objective C

The NSString Programming Guide recommends:

>If you simply want to determine whether a string contains a given pattern, you can use a predicate:

So, in your example:

NSString *data = @"abcde,";

// Create the predicate
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:@"SELF endswith %@", @","];

// Run the predicate
// match == YES if the predicate is successful
BOOL match = [myPredicate evaluateWithObject:data];

// Do what you want
if (match) {
    // do something
}

A bit long winded to write? Maybe, but if you do this in more than one place it can be easily refactored into a helper method.

Here's a link to the NSPredicate docs.

Edit

I've done some profiling and it is overkill in this simple case (see my comment below). I'll leave the answer up here anyway just as an example of using predicates for this sort of thing.

Solution 3 - Objective C

If you're worried about performance, and you want to check for one character, using -characterAtIndex: method may well be faster. -hasSuffix: takes a string, so potentially needs to do more work than just checking a single character (though the difference may be trivial).

You can also use categories to add a method to NSString like this:

@interface NSString(StringUtilities)
	- (BOOL) endsWithCharacter: (unichar) c;
@end

@implementation NSString(StringUtilities)

	- (BOOL) endsWithCharacter: (unichar) c
	{
		NSUInteger length = [self length];
		return (length > 0) && ([self characterAtIndex: length - 1] == c);
	}

@end

// test it...
NSString *data = @"abcd,";
if ([data endsWithCharacter: L','])
{

}

You should profile, of course, to be sure. Bear in mind though that by putting endsWithCharacter into a method we've added the message passing overhead to it, which will skew the profiling results unless you do the same when profiling the alternatives.

All of this is probably premature optimisation for most cases - but of course if you're doing this test thousands of times a second it may well matter (in that case you would probably want to use the code directly in the loop, as message passing inside a tight inner loop isn't a great plan).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionQuestionsView Question on Stackoverflow
Solution 1 - Objective Cuser269597View Answer on Stackoverflow
Solution 2 - Objective CAbizernView Answer on Stackoverflow
Solution 3 - Objective CSam DeaneView Answer on Stackoverflow