Is this the easiest way to compare NSStrings?


#1

I figured out the 2nd challenge but wholly molly, that whole NSOrderedSame, NSOrderedAscending… routine seemed overly complex for what it was trying to achieve. Isn’t there some easier way to compare NSStrings like

NSString *a = @“Tom”;
NSString *b = @“tom”;

if ([caseInSenstive a] == [caseInSenstive b])
{ NSLog …}

Or, alternatively you could check to see if they are not the same by:

if ([caseInSenstive a] != [caseInSenstive b])
{ continue; }

I find the options for comparing given in the book quite difficult to follow and rather opaque.

…Dale


#2

Leaving aside NSOrderedSame and NSOrderedAscending, there are two serious problems here:
The first problem has to do with syntax:[color=#FF0000] [caseInSenstive a][/color]
That should be: [a caseInSenstive]

The second problem is more serious; it has to do with semantics (the meaning): [caseInSenstive a] (should be [a caseInSenstive]) will return a pointer to an object. So does [caseInSenstive b]. Therefore, the if statement is testing two pointers for equality; but it should be testing the contents of the objects for equality.

Bad:

if ([caseInSenstive a] == [caseInSenstive b])
{ NSLog ...}

Good:

if ([[a caseInSenstive] isEqualTo:[b caseInSenstive]])
{
...
}

When learning a programming language, it is important to understand the difference between syntax and meaning. They are both equally important. Syntax enables us to express the meaning.


#3

Well, you make good points re: my syntax. But, I still wish there was an easier/more understandable way to do this.

How about this - a stringCompare Class method that returns a Boolean if two strings are equal or not with a Boolean caseSenstivity variable set to 1 if we care about caseSensitivity and set to 0 if we don’t:

NSString *a = @“Tom”;
NSString *b = @“tom”;

if ([stringCompare string1:a, string2:b, caseSensitive:1])
NSLog… ;

Anyway, I’m thinking that any number of approaches would be way easier to understand than the approach shown in the book.

…Dale


#4

You can easily do that by adding a category to the NSString class:

//  main.m

#import <Foundation/Foundation.h>
#import "NSString+MyStringAdditions.h"

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        NSString *a = @"Tom";
        NSString *b = @"tom";

        BOOL v = [a compareString1:a string1:b caseSensitive:YES];
        NSLog (@"%d", v);
        
        v = [a compareString1:a string1:b caseSensitive:NO];
        NSLog (@"%d", v);
    }
    return 0;
}

NSString+MyStringAdditions.h

// NSString+MyStringAdditions.h

#import <Foundation/Foundation.h>

@interface NSString (MyStringAdditions)
- (BOOL)compareString1:(NSString*)s1 string1:(NSString*)s2 caseSensitive:(BOOL)caseSensitive;
@end

NSString+MyStringAdditions.m

//  NSString+MyStringAdditions.m

#import "NSString+MyStringAdditions.h"

@implementation NSString (MyStringAdditions)

- (BOOL)compareString1:(NSString*)s1 string1:(NSString*)s2 caseSensitive:(BOOL)caseSensitive
{
    if (caseSensitive)
       return [s1 compare:s2] == NSOrderedSame;
    else
        return [s1 caseInsensitiveCompare:s2] == NSOrderedSame;
}
@end

#5

Wow! Thanks for going all out here.

Interesting to see that you/I could build a Class to do the compare the way I want to. But once you dig into the class it is ultimately implementing the NSOrderedSame etc. silliness I had hoped was avoidable.

I am understanding this but perhaps the whole OrderedSame, OrderedAscending, OrderedDescending approach implemented in these classes by Apple seems overly confusing. Maybe its just me. Maybe after using these for awhile they’ll make intuitive sense to me. But as they are they are counter-intuitive. I’m not ordering anything! I just want to know if they are the same or not.

You have gone above and beyond on this one my friend!

…Dale