Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using NSPredicate to search through array of objects

I have an array of instances of a class called Contact, which has, among others, the following properties:

NSArray *mailAddressList // Array of NSString
NSArray *websiteList // Array of NSString
NSArray *tags // Array of instances of Tag class

The class tag has the following properties:

NSString *name;
UIColor *color;

I want to use NSPredicate to search a string in any property of each Contact. This is the code I have:

if([scope isEqualToString:SCOPE_MAIL] || [scope isEqualToString:SCOPE_WEBSITE])
{
    // Search through an array
    predicate = [NSPredicate predicateWithFormat:@"ANY SELF.%@ contains[c] %@", scope, textSearch];
}
else if([scope isEqualToString:SCOPE_TAG])
{
    // Search another object's property
    predicate = [NSPredicate predicateWithFormat:@"SELF.%@.name contains[c] %@", scope, textSearch];
}
else
{
    // The rest of the properties are instances of NSString
    predicate = [NSPredicate predicateWithFormat:@"SELF.%@ contains[c] %@", scope, textSearch];
}

Everything works fine except for SCOPE_TAG, it doesn't return any values. I don't think I'm using the predicate correctly.

NOTE: I'm new with NSPredicate so I would like to hear some insights if what I'm doing is not ok

like image 823
Diego A. Rincon Avatar asked Dec 17 '13 05:12

Diego A. Rincon


People also ask

How to do an array search in an array of objects?

Searching in an array of objects can be done in Javascript using a loop, Array.find() or Array.findIndex() methods. Web Development Updates Javascript

How to use variable value in nspredicate?

As it is relatively time consuming for the app to parse the format string of the NSPredicate, we should try to reduce creating multiple NSPredicate and reuse similar NSPredicate as much as possible. We can use variable value in NSPredicate denoted by $ sign, and substitute its value by calling withSubstitutionVariables method.

How do I search for a primitive or findindex in JavaScript?

Use indexOf () to search for a primitive or findIndex () to search with a function. Continue your JavaScript learning with iteration methods, accessor methods, and mutator methods. Want to learn more? Join the DigitalOcean Community!

How do I use%@ and%I in a predicate?

Say for a predicate which select Person that have a name “Asriel” and 50 money : The format is "name == %@ AND money == %i". %@ and %i are the format specifiers, %@ will be substituted with an object (eg: String, date etc), whereas %i will be substituted with an integer.


1 Answers

First of all, if you substitute a keypath you should use %K as arg.

Further, I think you are missing the ANY argument in your second query. I think you want a result if any of the tag names contains your textSearch.

To get a better understanding of how predicates work, have a look at the Apple Documentation

I did a quick test and it is still working fine:

NSMutableArray *arrayContacts = [NSMutableArray array];

{
    AMContact *contact = [[AMContact alloc] init];
    NSMutableArray *arrayTags = [NSMutableArray array];
    {
        AMTags *tag = [[AMTags alloc] init];
        tag.name = @"Test";
        [arrayTags addObject:tag];
    }

    {
        AMTags *tag = [[AMTags alloc] init];
        tag.name = @"Te2st2";
        [arrayTags addObject:tag];
    }

    {
        AMTags *tag = [[AMTags alloc] init];
        tag.name = @"No";
        [arrayTags addObject:tag];
    }
    contact.tags = [arrayTags copy];
    [arrayContacts addObject:contact];
}

{
    AMContact *contact = [[AMContact alloc] init];
    NSMutableArray *arrayTags = [NSMutableArray array];
    {
        AMTags *tag = [[AMTags alloc] init];
        tag.name = @"Test";
        [arrayTags addObject:tag];
    }
    contact.tags = [arrayTags copy];
    [arrayContacts addObject:contact];
}
NSPredicate *pred = [NSPredicate predicateWithFormat:@"ANY SELF.%K.name contains[c] %@", @"tags", @"Test"];

NSArray *result = [arrayContacts filteredArrayUsingPredicate:pred];

NSLog(@"%@", result);
like image 100
Alexander Avatar answered Sep 23 '22 02:09

Alexander