casillas
casillas

Reputation: 16813

NSPredicate does not return the expected items

I am trying to find an items in the array where itemId and size are not matched. However, the following query does not return me item(s) where itemId same but size different. I wonder what I am missing.

First I am extracting the item as follows, then I am trying to find compliment of this item.

NSPredicate *itemPredicate = [NSPredicate predicateWithFormat:@"(%K == %@)", kItemId, itemId];
NSPredicate *sizePredicate = [NSPredicate predicateWithFormat:@"(%K == %@)", kSize, [NSString stringWithFormat:@"%d", size]];
NSPredicate *combinedPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[itemPredicate, sizePredicate]];
NSArray *itemInOrder = [sharedData.orderItems filteredArrayUsingPredicate:combinedPredicate];

Trying to extract complimentary items of itemInOrder

NSPredicate *restOfOrderPredicate = [NSPredicate predicateWithFormat:@"(%K != %@)", kItemId, itemId];
NSPredicate *restSizePredicate = [NSPredicate predicateWithFormat:@"(%K != %@)", kSize, [NSString stringWithFormat:@"%d", size]];
NSPredicate *restCombinedPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[restSizePredicate, sizePredicate]];
NSMutableArray *restOfItemsInOrder = [NSMutableArray arrayWithArray:[sharedData.orderItems filteredArrayUsingPredicate:restOfOrderPredicate]];

Upvotes: 1

Views: 86

Answers (1)

ghostatron
ghostatron

Reputation: 2650

I think there are 2 issues here:

  1. Your complementary and predicate is using the sizePredicate, but I think you want to be using restSizePredicate.

  2. I think you want to use an or predicate. As you have it now, you'll miss anything that has just the same size or just the same itemId.

An alternate approach could be to use a fetch that gets all the objects. Then use your existing fetch to get the original set you wanted. Then use Set Arithmetic to remove the second set from the first.

** EDIT **

  1. I just now discovered notPredicateWithSubpredicate which is probably exactly what you want: Keep your first query and predicate as is. Then for the second query, use notPredicateWithSubpredicate and pass in your predicate from the first query.

Upvotes: 1

Related Questions