I have a large number of different NSObject types that all have different properties and I am trying to abstract out a single method that will allow me to filter the NSArrays of the objects by simply passing in an NSArray of properties I wish to filter on. The number keys I filter on vary from possibly 1 to whatever.
Here is an example of the filtering NSArray
NSArray *filterBy = [NSArray arrayWithObjects:
#"ManufacturerID",
#"CustomerNumber",nil];
These keys also exist in the objects of my NSArray I am filtering, so basically this would need to generate something like this:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"%K == %# AND %K == %#",
[filterBy objectAtIndex:0],
[items valueForKey: [filterBy objectAtindex:0],
[filterBy objectAtIndex:1],
[items valueForKey: [filterBy objectAtIndex:1]];
Which would generate something like: ManufacturerID==18 AND CustomerNumber=='WE543'
Is it possible to do this?
This is easy. Check it out:
NSMutableArray *subpredicates = [NSMutableArray array];
for (NSString *filterKey in filterBy) {
NSString *filterValue = [items valueForKey:filterKey];
NSPredicate *p = [NSPredicate predicateWithFormat:#"%K = %#", filterKey, filterValue];
[subpredicates addObject:p];
}
NSPredicate *final = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
Related
I'm trying to filter two keys with the text in my search bar. See my code below so far, but it crashes my app.
NSSet *keys = [NSSet setWithObjects:#"node_title", #"address", nil];
self.filteredStores = [self.storesData filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"%K contains[c] %#", keys, self.searchBar.text]];
I feel like I'm on the right track, but I'm unable to do this successfully. Help is appreciated!
One option...
NSSet *keys = [NSSet setWithObjects:#"node_title", #"address", nil];
NSMutableArray *subpredicates = [NSMutableArray array];
for (NSString *k in keys) {
NSPredicate *p = [NSPredicate predicateWithFormat:#"%K contains[c] %#", k, self.searchBar.text];
[subpredicates addObject:p];
}
NSPredicate *final = [NSCompoundPredicate orPredicateWithSubpredicates:subpredicates];
self.filteredStores = [self.storesData filteredArrayUsingPredicate:final];
I have a NSMutableArray of objects with tag attributes assigned to them. I am trying to find if any of these objects have a tag assigned to them of the string value "a".
my code so far:
for (Object *object in self.array)
{
NSDictionary *attrs = [object propertyValue:#"attrs"];
NSString *tag = attrs[#"tag"];
}
Can I do something like:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"a"];
NSArray *results = [self.array filteredArrayUsingPredicate:predicate];
not sure how it works?
Try this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"tag == %#", #"a"];
NSArray *result = [NSMutableArray arrayWithArray:[self.array filteredArrayUsingPredicate:predicate]];
Use 'contains[c]' instead of '==' if you want to perform case-insensitive search.
If you want to filter for any other property, replace 'tag' with that property name.
You will need to do something more like :
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.property_name contains[c] '%#'", #"a"];
NSArray *result = [NSMutableArray arrayWithArray:[self.array filteredArrayUsingPredicate:predicate]];
I have array of dictionaries, dictionary contains key as NSString and value as integer. I have tried the following code but not getting result.
NSPredicate *objPredicate = [NSPredicate predicateWithFormat:#"%# = %#", key, [NSNumber numberWithInt:value]];
NSArray *filteredArray = [array filteredArrayUsingPredicate:objPredicate];
Use this:
NSPredicate *objPredicate = [NSPredicate predicateWithFormat:#"self[%#] = %#", key, #(value)];
NSArray *filteredArray = [array filteredArrayUsingPredicate:objPredicate];
I have an NSArray with objects that have a name property.
I would like filter the array by name
NSString *alphabet = [agencyIndex objectAtIndex:indexPath.section];
//---get all states beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", alphabet];
NSMutableArray *listSimpl = [[NSMutableArray alloc] init];
for (int i=0; i<[[Database sharedDatabase].agents count]; i++) {
Town *_town = [[Database sharedDatabase].agents objectAtIndex:i];
[listSimpl addObject:_town];
}
NSArray *states = [listSimpl filteredArrayUsingPredicate:predicate];
But I get an error - "Can't do a substring operation with something that isn't a string (lhs = <1, Arrow> rhs = A)"
How can I do this? I would like to filter the array for the first letter in name being 'A'.
Try with following code
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF like %#", yourName];
NSArray *filteredArr = [yourArray filteredArrayUsingPredicate:pred];
EDITED :
NSPredicate pattern should be:
NSPredicate *pred =[NSPredicate predicateWithFormat:#"name beginswith[c] %#", alphabet];
Here is one of the basic use of NSPredicate for filtering array .
NSMutableArray *array =
[NSMutableArray arrayWithObjects:#"Nick", #"Ben", #"Adam", #"Melissa", #"arbind", nil];
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"SELF contains[c] 'b'"];
NSArray *beginWithB = [array filteredArrayUsingPredicate:sPredicate];
NSLog(#"beginwithB = %#",beginWithB);
NSArray offers another selector for sorting arrays:
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(Person *first, Person *second) {
return [first.name compare:second.name];
}];
If you want to filter array take a look on this code:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#", #"qwe"];
NSArray *result = [self.categoryItems filteredArrayUsingPredicate:predicate];
But if you want to sort array take a look on the following functions:
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context hint:(NSData *)hint;
- (NSArray *)sortedArrayUsingSelector:(SEL)comparator;
visit https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Arrays.html
use this
[listArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
Checkout this library
https://github.com/BadChoice/Collection
It comes with lots of easy array functions to never write a loop again
So you can just do
NSArray* result = [thArray filter:^BOOL(NSString *text) {
return [[name substr:0] isEqualToString:#"A"];
}] sort];
This gets only the texts that start with A sorted alphabetically
If you are doing it with objects:
NSArray* result = [thArray filter:^BOOL(AnObject *object) {
return [[object.name substr:0] isEqualToString:#"A"];
}] sort:#"name"];
I want to search a specific string in the array of strings in objective c. Can somebody help me in this regard?
BOOL isTheObjectThere = [myArray containsObject: #"my string"];
or if you need to know where it is
NSUInteger indexOfTheObject = [myArray indexOfObject: #"my string"];
I strongly recommend you read the documentation on NSArray. It's best to do that before posting your question :-)
You can use NSPredicate class for searching strings in array of strings.
See the below sample code.
NSMutableArray *cars = [NSMutableArray arrayWithObjects:#"Maruthi",#"Hyundai", #"Ford", #"Benz", #"BMW",#"Toyota",nil];
NSString *stringToSearch = #"i";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",stringToSearch]; // if you need case sensitive search avoid '[c]' in the predicate
NSArray *results = [cars filteredArrayUsingPredicate:predicate];
This is the most efficient way for searching strings in array of strings
NSMutableArray *cars = [NSMutableArray arrayWithObjects:#"Max",#"Hai", #"Fine", #"Bow", #"Bomb",#"Toy",nil];
NSString *searchText = #"i";
NSArray *results = [cars filteredArrayUsingPredicate:predicate];
// if you need case sensitive search avoid '[c]' in the predicate
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"title contains[c] %#",
searchText];
searchResults = [cars filteredArrayUsingPredicate:resultPredicate];