Gareth Jeanne
Gareth Jeanne

Reputation: 1420

Filtering NSArray with Predicate leaves extra result?

I have an NSArray containing NSDictionary objects.

I need to filter the objects based on a selection of values, so i have created an array of the values i want to filter by and using a predicatewithformat and feeding it the array of objects.

This is kind of working, but weirdly in situations where i know i should be getting an empty array returned i am getting a single object, that shouldn't be there.

I have logged out the value of the array of filter values, and i can clearly see that it contains a key which corresponds to the id_str of the object, so it shouldn't be returned.

Below is the code i am using, any pointers of where i am going wrong would be very vert helpful!

                 //Create new fetch request
             NSFetchRequest *request = [[NSFetchRequest alloc] init];

             //Set new predicate to only fetch tweets that have been favourited
             NSPredicate *filterFavourite = [NSPredicate predicateWithFormat:@"favouriteTweet == 'YES'"];

             //Setup the Request
             [request setEntity:[NSEntityDescription entityForName:@"Tweet" inManagedObjectContext:_managedObjectContext]];

             //Assign the predicate to the fetch request
             [request setPredicate:filterFavourite];
             NSError *error = nil;

             //Create an array from the returned objects
             NSArray *favouriteTweets = [_managedObjectContext executeFetchRequest:request error:&error];
             NSAssert2(favouriteTweets != nil && error == nil, @"Error fetching events: %@\n%@", [error localizedDescription], [error userInfo]);

             //Create a new array containing just the tweet ID's we are looking for
             NSArray *favouriteTweetsID = [favouriteTweets valueForKey:@"tweetID"];

             NSLog(@"%@", favouriteTweetsID);

             //Create a new predicate which will take our array of tweet ID's
             NSPredicate *filterFavouritsearchPredicate = [NSPredicate predicateWithFormat:@"(id_str != %@)" argumentArray:favouriteTweetsID];

             //Filter our array of tweet dictionary objects using the array of tweet id's we created
             NSArray *filteredTweets = [self.timelineStatuses filteredArrayUsingPredicate:filterFavouritsearchPredicate];

             //Send those tweets out to be processed and added to core data
            [self processNewTweets:filteredTweets];

             NSLog(@"Update Favoutited Tweets: %@", filteredTweets);

Upvotes: 0

Views: 374

Answers (1)

Martin R
Martin R

Reputation: 539965

This is probably not doing what you intent:

[NSPredicate predicateWithFormat:@"(id_str != %@)" argumentArray:favouriteTweetsID];

It is equivalent to

[NSPredicate predicateWithFormat:@"(id_str != %@)", id1, id2, ... idN];

where id1, id2, ..., idN are the elements of favouriteTweetsID. The format string has only one format specifier, so that everything but the first element is ignored and you just have

[NSPredicate predicateWithFormat:@"(id_str != %@)", id1];

If you want to filter all objects where id_str is not equal to any of the array elements, use

[NSPredicate predicateWithFormat:@"NOT id_str IN %@", favouriteTweetsID];

Upvotes: 4

Related Questions