Question

I'm trying to get the position of an object inside an array, and if the object is not there, i want to insert it. The weird thing is that the last "Copy" string is returning NSNotFound, and i just can't imagine why.

NSMutableArray *original = [[NSMutableArray alloc] init];
NSMutableArray *new = [[NSMutableArray alloc] init];
[original addObject:@"Copy"];
[original addObject:@"Copy"];
[original addObject:@"Table"];
[original addObject:@"Table"];
[original addObject:@"Camper"];
[original addObject:@"Copy"];

for (NSString *string in original) {
    NSUInteger i = [new indexOfObject:string inSortedRange:NSMakeRange(0, [new count]) options:NSBinarySearchingFirstEqual usingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2];
    }];

    if (i == NSNotFound) {
        [new addObject:string];
    }

    NSLog(@"%lu", (unsigned long)i);
}

I know i can do it in other ways but i just want to understand whats wrong with that. This is the NSLog:

2147483647 (NSNotFound)
0
2147483647 (NSNotFound)
1
2147483647 (NSNotFound)
2147483647 (NSNotFound) WHY ?????
Was it helpful?

Solution

You're misusing the the method indexOfObject:inSortedRange:. That method should only be used on pre-sorted arrays, the array you're checking is not sorted. Your array is not sorted, since "Camper" would come before all of the other objects in that array. The indexOfObject:inSortedRange: has undefined behavior when you give it an unsorted array.

Here's the correct way to do what you want. There are other NSArray methods available for finding indexes, if you want to have different options or methods of determining equality.

NSMutableArray *original = [[NSMutableArray alloc] init];
NSMutableArray *new = [[NSMutableArray alloc] init];
[original addObject:@"Copy"];
[original addObject:@"Copy"];
[original addObject:@"Table"];
[original addObject:@"Table"];
[original addObject:@"Camper"];
[original addObject:@"Copy"];

for (NSString *string in original) {
    NSUInteger i = [new indexOfObjectWithOptions:0 passingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [string compare:obj] == NSOrderedSame;
    }];

    if (i == NSNotFound) {
        [new addObject:string];
    }

    NSLog(@"%lu", (unsigned long)i);
}

See NSArray documentation for more information.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top