Find objects which contains subjects with given parameter - ios

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.

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);
}

Challenge : Best way to check if model object array contains properties of model in Objective-C

Model = CountryCode
#property (nonatomic, retain) NSString * abbreviation;
#property (nonatomic, retain) NSNumber * code;
#property (nonatomic, retain) NSString * name;
Model array = CountryCodesArray
Problem:
I have countrycode for eg: 81
I want to check if 81 is in my model array or not ??
Query:
I want to make the process efficient.
I dont' want to check in for in loop like as :
for (CountryCode * countcode in Countrycodes) {
NSLog(#"\n%#", countcode.code);
}
Tried fast enumeration , but crashed , any suggestions ??
BOOL isCodePresent = [[Countrycodes valueForKeyPath:#"CountryCode.code"] containsObject:#"81"];
Thanks in advance.
Without doing a loop you can use the filteredArrayUsingPredicate
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"code == 81"];
NSArray *filtered = [countryCodesArray filteredArrayUsingPredicate:predicate];
Then if you need the object:
CountryCode *countcode = (CountryCode*)[filtered objectAtIndex:0];

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.

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.

how to fetch a particular value using NSFetchRequest

I need to fetch a particular managed entity where value is xxx.
my managed object is
Subscriptions : NSManagedObject{
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) NSNumber * id;
#property (nonatomic, retain) NSNumber * category;
#property (nonatomic, retain) NSNumber * frequency;
#property (nonatomic, retain) NSNumber * alertType;
}
I need to fetch only the one entities where name is "xxx".
(There will be only one entities where name is xxx.)
I also need to fetch all entities where category is 1.
How can I do this using NSFetchRequest. I know how to use NSFetchedResultsController to fetch all entity values for an entity, but I want to fetch only one where name is xxx.
Suppose you have a NSManagedObjectContext *context, then:
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; //Note don't use autorelease if you're using ARC
request.entity = [NSEntityDescription entityForName:#"Subscriptions" inManagedObjectContext:context];
NSString *someName = #"xxx";
request.predicate = [NSPredicate predicateWithFormat:#"name ==[c] %#", someName]; //[c] means case insensitive
NSArray *result = [context executeFetchRequest:request error:nil];
The result array will contain all returned results and will be of type Subscriptions. If the predicate matches only one item there will be only one result, if matches none, the array would be initialized, but its count property would be 0. You may take a look at NSPredicate Class Reference and how you use it with CoreData.

Resources