1

I have a NSMutableArray pages with several objects (instances of Page). Each Page instance has a UUID and other properties, such as contents. When a page changes, everything may change except the UUID. After a change, I would like to find out the index of a particular Page in pages by using indexOfObject:. I use the UUID to identify the index I'm looking for and this works just fine:

NSMutableArray *uuids = [[NSMutableArray alloc] init];
for (int i = 0; i < [self.pages count]; i++) {
    [uuids addObject:[[pages objectAtIndex:i] uuid]];
}

NSUInteger indexOfPage = [uuids indexOfObject:page.uuid];

Now my question is if there is a more elegant way to do this. All I really need is the index of the Page object in pages that has a given UUID.

There is - (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate or indexOfAccessibilityElement:<#(id)#> but I'm not really sure how either of these could help me out with my problem.

3 Answers 3

3

Subclass the isEqual: method in Page as follows:

- (BOOL) isEqual: (Page *) otherPage
{
    if (![otherPage isKindOfClass:[Page class]]) {
        return NO;
    }

    return [self.UUID isEqualToString: otherPage.UUID];
}

Then indexOfObject: will work correctly.

From Apple's NSArray documentation:

Starting at index 0, each element of the array is sent an isEqual: message until a match is found or the end of the array is reached. This method passes the anObject parameter to each isEqual: message. Objects are considered equal if isEqual: (declared in the NSObject protocol) returns YES.

Sign up to request clarification or add additional context in comments.

Comments

2

From NSArray docs:

each element of the array is sent an isEqual: message until a match is found or the end of the array is reached.

So you can override isEqual: so that it returns YES if the two pages has the same UUID.

- (BOOL)isEqual:(id)object {
    if (![object isKindOfClass:[Page class]]) {
        return NO;
    }

    Page *otherPage = object;
    return [self.uuid isEqualToString:otherPage.uuid];
}

2 Comments

Thanks Hejazi. Just wondering if I really need the isKindOfClass. I've implemented Ahsley's and it works just fine, but perhaps yours is the correct and saver answer. Can you explain why you are checking isKindOfClass?
Just in case. So that when I'm accessing uuid I know it's there and I'm not comparing with an object from another class.
0

May be this way by using a predicate, assuming pages is your array of all pages:

predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(UUID == %@)", searchUUID]];
filteredArray = [pages filteredArrayUsingPredicate:predicate];

And once you have the object, which should be at objectAtIndex:0 in the filtered array assuming your uuid is unique, you could ask the index of that object:

NSUInteger indexOfPage = [pages indexOfObject:theObject];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.