Apply NSPredicate to Array which is inside an a dictionary IOS - ios

#interface Contact : NSObject
#property (assign, nonatomic) NSInteger *cid;
#property (strong, nonatomic) NSString * name;
#property (strong, nonatomic) NSMutableArray *arrPhone;
#end
I have created "Contact" NSObject for above dictionary which has arrPhone array.
Now I have an array which has list of contact object. Now i need those contact object whose phone array contains number which starts with #"11" (my search string)
I have tried the following:
NSPredicate *p1 =[NSPredicate predicateWithFormat:#"arrPhone contains[cd] %#)",searchText];
But its not working. Please help.

Since arrPhone is itself an array, you need to test whether any of its members matches your search criteria, not whether it does. So amend your predicate to use ANY:
NSPredicate *p1 =[NSPredicate predicateWithFormat:#"ANY arrPhone contains[cd] %#)",searchText];

Try this
[collection[#"phone"] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF beginswith[c] '11'"]];

Related

Subquery and IN Statement in realm

I have three realm objects. Department, section and user. section is a kind of sub department in a department. But there will be users under each section and each department.
#interface Department : RLMObject
#property NSString *name;
#property BOOL isCollapsed;
#property (nonatomic, strong) RLMArray<Section> *sections;
#property (nonatomic, strong) RLMArray<User> *users;
#end
#interface Section : RLMObject
#property NSString *name;
#property BOOL isCollapsed;
#property RLMArray<User> *users;
#end
#interface User : RLMObject
#property NSString *department;
#property NSString *email;
#property NSString *firstname;
#property NSString *lastname;
#property NSString *fullname;
#end
What i want to do is, I want to search all the user whose first name and last name contains "a" and linked with department and section.
Now what i am doing is
searchText = [searchText lowercaseString];
RLMResults *sections = [Section objectsWhere:
[NSString stringWithFormat:#"SUBQUERY(users, $user, $user.fullname contains '%#' OR $user.nickname contains '%#').#count > 0",searchText,searchText]];
NSMutableArray *sectionNames = [NSMutableArray array];
for (Section *section in sections)
{
[sectionNames addObject:section.name];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SUBQUERY(sections, $section, $section.name IN %#).#count > 0", sectionNames];
RLMResults *filteredDepartments = [[Department objectsWithPredicate:predicate] sortedResultsUsingProperty:#"name" ascending:YES];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SUBQUERY(users, $user, $user.fullname contains %# OR $user.nickname contains %#).#count > 0",searchText,searchText];
RLMResults *departments = [filteredDepartments objectsWithPredicate:pred];
Right now the issue is there is two sections in sections array but in the deparments results, it returns null. please help. thanks.
Note: If one user already belongs to section then that user will not be include in department.
Maybe you do not need to use subquery. More simply, you can use ANY in query like the following:
[Department objectsWhere:
#"ANY users.firstname CONTAINS %# OR ANY users.lastname CONTAINS %# OR ANY sections.users.firstname CONTAINS %# OR ANY sections.users.lastname CONTAINS %#", searchText, searchText, searchText, searchText];
But I think using inverse relationships is more easier. In Realm, inverse relationships is defined with RLMLinkingObjects.
You can add inverse relationships to User class as follows:
#interface User : RLMObject
...
#property (readonly) RLMLinkingObjects *departments;
#property (readonly) RLMLinkingObjects *sections;
#end
#implementation User
+ (NSDictionary *)linkingObjectsProperties {
return #{#"departments": [RLMPropertyDescriptor descriptorWithClass:Department.class propertyName:#"users"],
#"sections": [RLMPropertyDescriptor descriptorWithClass:Section.class propertyName:#"users"]};
}
#end
Then you can get departments and sections where the user belongs to from User's property, like the following:
RLMResults *users = [User objectsWhere:#"firstname CONTAINS %# OR lastname CONTAINS %#" , searchText, searchText];
for (User *user in users) {
NSLog(#"%#", user.departments);
NSLog(#"%#", user.sections);
}

list of indexes in NSArray from NSPredicate

My question is very similar to : obj c -get list of indexes in NSArray from NSPredicate
But there is a difference. I have two NSArrays. The first is of names and the other is of phone numbers. I search into the "names" array to search for a name using the following code:
-(void)filterContentForSearchText:(NSString *)searchtext scope:(NSString *)scope {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#",searchtext];
self.searchResult = [ForMsgNamrarray filteredArrayUsingPredicate:predicate];
}
I am returned a filtered array which is fine. But based on the indexes of the filtered array I would also like to filter the array containing the phone numbers.
For example if I search "jh" I get "Jhone" in my search array. I also want to add the phone number of john in another array i.e "searchArrayPhNum"
Prepare a Model Object with following properties,
#interface Person : NSObject
#property (nonatomic,retain) NSString *name;
#property (nonatomic,retain) NSString *phoneNumber;
#end
and use single array ( an array of Person objects) instead of Two different arrays,
Your predicate would change like,
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name beginswith[c] %#",searchtext];

NSPredicate for property of object in NSArray of NSArray

I have an objects like the below structure: Transaction has an array of Items. Item has an array of SubItems
#interface Transaction : NSObject
#property (nonatomic, copy) NSString *id;
#property (nonatomic, assign) NSInteger status;
#property (nonatomic, strong) NSArray *items; // array of Item
#end
#interface Item : NSObject
#property (nonatomic, copy) NSString *identifier;
#property (nonatomic, assign) NSInteger price;
#property (nonatomic, strong) NSArray *subitems;
#end
#interface SubItem : NSObject
#property (nonatomic, copy) NSString *name;
#property (nonatomic, assign) NSInteger price;
#end
I would like to create predicate to find name and price of Subitem from NSArray of Transaction
pred = [NSPredicate predicateWithFormat:
#"ANY SELF.%K.%K.%K contains %#",
#"items",
#"subitems",
#"name",
#"MY_SUB_ITEM_NAME"];
This generates the error below.
failed: caught "NSInvalidArgumentException", "Can't do regex matching
on object (
MY_SUB_ITEM_NAME )."
However when I use the similar format to find out properties in Transaction. It works fine.
pred = [NSPredicate predicateWithFormat:
#"SELF.%K LIKE %#",
#"identifier",
#"TX001"];
How should I correct my predicate to query property in Item and SubItem
I think that cannot work with -predicateWithFormat: for two aggregation levels. On each level you can have a ANY or an ALL aggregation. So the "right" syntax would be ANY items ANY subitems.… = …. Or ANY items ALL subitems.…= …" or …
You can try to build the predicate manually with NSExpression, probably using subqueries.
Oh, you are not using Core Data, what I assumed. So simply do it manually in a loop or use a computed property.

Find objects which contains subjects with given parameter

I'm trying to figure out NSPredicate which will find all objects which contains subjects with given parameter.
I have this objects:
#interface User : NSManagedObject
#property (nonatomic, strong) NSString * name;
#property (nonatomic, strong) NSMutableOrderedSet * items;
#end
and:
#interface Item : NSManagedObject
#property (nonatomic, strong) NSNumber * itemId;
#end
I have array of users and I want to find all users which contain item with itemId == 1.
Have no more clues how to get it
NSNumber *theItemId = #1; // The id that you are looking for
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY items.itemId == %#", theItemId];
should do it. You can use this predicate in a fetch request to fetch all matching users,
or with filteredArrayUsingPredicate: to filter an array of users.

NSPredicate and custom NSObject

I have a custom NSObject which I need to filter. I have been trying to user NSPredicate to do this, but was unable to so far. Here is my object's structure:
#interface MyBigObject : NSObject
#property (nonatomic, strong) NSString *firstAttribute;
#property (nonatomic, strong) NSString *secondAttribute;
#property (nonatomic, strong) NSMutableArray *featuresArray;
#end
The featuresArray contains other custom objects:
typedef enum {
FeatureExists = YES, //Default
FeatureDoesNotExist = NO,
FeatureNotAvailable
} FeatureValue;
#interface MySmallObject : NSObject
#property (nonatomic, strong) NSString *title;
#property (nonatomic) FeatureValue feature;
#end
I want to only return the objects containing a MySmallObject with a certain title and which has feature == FeatureExists.
I've tried something like (and other variations) but to no success:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SUBQUERY(featuresArray, $object, $object.title CONTAINS[c] %# AND $object.feature = %d).#count > 0)", #"Fenced", FeatureExists];
NSLog(#"predicate = %#", predicate);
If I understood correctly, the format of your predicate is wrong. It should be [NSPredicate predicateWithFormat:#"SUBQUERY(featuresArray, $object, $object.title CONTAINS[c] %# AND $object.feature = %d).#count > 0", #"some string", FeatureExists]; where you check in your array if any object matches the requirements.

Resources