1

I have 2 arrays, one contains a set of ID's and one contains a set of objects (similar to below):

NSArray *identifierArray = @[@100, @200, @300];
NSArray *peopleArray = @[@{@"id": @100, @"name": @"Ben"}, @{@"id": @200, @"name": @"Alex"}, @{@"id": @300, @"name": @"Sarah"}, @{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}];

I want to be able to loop through the peopleArray and check if any of the objects has an ID that appears in identifierArray. If a match is found, it should remove the object from the identifierArray, which would result in:

NSArray *peopleArray = @[@{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}];

I've tried some variations of for loops to loop through each object, then loop through each ID in peopleArray, as below, but it doesn't remove any objects, even though there are objects it should be removing.

    for (NSNumber *id in activePeople) {
        for (int i = 0; i < peopleArray.count; i++) {
            if (id == [peopleArray[i] valueForKey:@"id"]) {
                NSLog(@"Should remove...%@")
            }
        }
    }

Can anyone point me in the direction of how i might go about this?

1
  • I'm voting to close this question as off-topic because this homework question Commented Sep 13, 2018 at 8:35

2 Answers 2

3

My suggestion is to drop loops and use the more contemporary block based API indexesOfObjectsPassingTest (which actually exists since 2009 in macOS 10.6 Snow Leopard and iOS 4.0 ).

NSArray *identifierArray = @[@100, @200, @300];
NSMutableArray *array = [@[@{@"id": @100, @"name": @"Ben"}, @{@"id": @200, @"name": @"Alex"}, @{@"id": @300, @"name": @"Sarah"}, @{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}] mutableCopy];
NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^BOOL(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
    return [identifierArray containsObject:obj[@"id"]];
}];
[array removeObjectsAtIndexes:indexes];
NSLog(@"%@", array);

Or still more efficient filtering the array with a predicate (available since macOS 10.4 Tiger and iOS 3.0 in 2005(!))

NSArray *identifierArray = @[@100, @200, @300];
NSArray *array = @[@{@"id": @100, @"name": @"Ben"}, @{@"id": @200, @"name": @"Alex"}, @{@"id": @300, @"name": @"Sarah"}, @{@"id": @400,@"name": @"George"}, @{@"id": @500, @"name": @"Jessica"}];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT id IN %@", identifierArray];
NSArray *result = [array filteredArrayUsingPredicate:predicate];
NSLog(@"%@", result);

If the id values should be strings replace all occurrences of @x00 with @"x00"

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

6 Comments

Given both a try but both seem to not remove the objects with an ID of 100, 200 or 300. I must be missing something...
Both snippets are supposed to work stand-alone. Are the IDs really NSNumber objects?
Ah, think i may have solved it using the predicate example you gave, just changing predicateWithFormat:@"NOT id IN %@", identifierArray] to predicateWithFormat:@"id == %@", identifierArray]. If you can update your answer, i'll happily accept, hopefully help someone else out in the future. Appreciate the help!
If you want to keep 400 and 500 as described in the question the code is correct, @"id == %@", identifierArray cannot work.
Ah, as you mention it, i just printed the data type of the id in the array in the example and it's actually NSTaggedPointerString, and the id in identifierArray is __NSCFNumber which must be why it hasn't worked for me.
|
1

You very likely cannot use == to compare the two objects in this case, but instead use isEqual:

== compares the values of pointers. In your case it seems that they will not be the same.

isEqual: instead compares the objects itself.

To reuse your code you can try this:

for (NSNumber *id in activePeople) {
    for (int i = 0; i < peopleArray.count; i++) {
        if ([id isEqual:[peopleArray[i] valueForKey:@"id"]) {
            NSLog(@"Should remove...%@")
        }
    }
}

1 Comment

Just given this a try but doesn't seem to remove the object (/ the NSLog is not printing to the console)?

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.