Hello I have a NSMutableArray like this
Contactarray (
{
"firstNAme"="name1"
"lastName"="name2"
"phoneNumber"="12345678902";
}
{
"firstNAme"="name1"
"lastName"="name2"
"phoneNumber"="12345678902";
}
I want to search the person when I type the person name in my UITextField. Then the filtered UItableView should be loaded. This NSMutableArray contains NSMutableDictionaries.
How can I find the matching object from these objects?
Lets say I want to search all name1 people. Then I want to find all the objects containing "name1" and those objects should fill to another array to load the UITableview
Please help me.
Thanks.
UPDATE
This is my contacts array
<__NSArrayI 0x7b601f70>(
firstname = Kate;
lastName = Bell;
phone = "(415) 555-3695";
userimg = "<UIImage: 0x7b67b3a0>";
};
{
firstname = Kate;
lastName = Bell;
phone = "(415) 555-3695";
userimg = "<UIImage: 0x7b67b3a0>";
},
This is my code for search
`
[playlistArray removeAllObjects];
NSArray *contacts=[[NSArray alloc] initWithArray:mutArraySearchContacts];
NSPredicate *filter = [NSPredicate predicateWithFormat:#"firstname = %# OR lastName = %#",currentSrchStr,currentSrchStr];
playlistArray=[contacts filteredArrayUsingPredicate:filter];
[self performSelectorInBackground:#selector(playlistsLoaded) withObject:nil];
`
But my playlistArray is empty.
`
(lldb) po playlistArray
<__NSArrayI 0x7b74adf0>(
)
`
What is the wrong I have done here?
No need to iterate while you use NSPredicate. Try this.
NSPredicate * myPredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"SELF['firstNAme'] contains '%#' || SELF['lastName'] contains '%#'",currentSrchStr,currentSrchStr]];
NSArray *filterArray = [mutArraySearchContacts filteredArrayUsingPredicate:myPredicate];
NSLog(#"filterArray %#", filterArray);
Update 1:
Modify your predicate with CONTAIN[C] for case insensitive, like
NSPredicate * myPredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"SELF['firstNAme'] CONTAINS[c] '%#' || SELF['lastName'] CONTAINS[c] '%#'",currentSrchStr,currentSrchStr]];
Hope this helps you !!
NSArray *contacts = ...; //your array of NSDictionary objects
NSPredicate *filter = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"firstName == %#", #"name1"]];
NSArray *filteredContacts = [contacts filteredArrayUsingPredicate:filter];
If you need to search with more condition, like full name:
NSPredicate *filter = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"firstName == %# OR lastName == %#" ,#"name1", #"name2"]];
Here is Predicate Programming Guide, which illustrates more advanced features.
You can use keysOfEntriesPassingTest: method to find all keys where the value equals #"test".
In the implementation below only the first key will be found. If you need all keys where the object is #"Test", do not assign *stop.
NSString *target = #"test";
NSSet *keys = [myDictionary keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop)
{
return (*stop = [target isEqual:obj]);
}];
when u get the key you can proceed further.
Related
I'm trying to use the input on an NSTextField along with NSPredicate to populate a NSMutableArray of like objects.
In my app I have the following simple NSMutableArray
{
firstName = Danton;
phoneNumbers = 5555555555;
}
Now, I am using the following code to try and filter the results as the user types (if "Dan" is in the textField, the filtered array should include the above object)
NSMutableArray *filteredArray = [[NSMutableArray alloc] init];
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"firstName CONTAINS[cd] %#", self.searchField.text];
filteredArray = [[filteredArray filteredArrayUsingPredicate:sPredicate] mutableCopy];
NSLog(#"Filtered values: %#", filteredArray);
However, I am getting an empty return on filteredArray. Can someone tell me what is wrong with my code?
NSArray *array = #[
#{
#"firstName" : #"Danton", #"phoneNumbers" : #"5555555555"
}
];
NSArray *result = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"%K contains[c] %#", #"firstName", #"Dan"]];
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]];
How do I filter an array of objects by a specific field?
My code:
NSMutableArray *inputArray = [[NSMutableArray alloc]init];
Person *person = [[Person alloc]init];
person.first_name = #"John";
[inputArray addObject: person];
person = [[Person alloc]init];
person.first_name = #"Jack";
[inputArray addObject: person];
NSString *expression = [NSString stringWithFormat:#"SUBQUERY(inputArray, $object, $object.first_name CONTAINS[c] J"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:expression];
NSMutableArray *filteredArray = [[inputArray filteredArrayUsingPredicate:predicate]mutableCopy];
NSLog(#"Count should be 2: %lu",(unsigned long)filteredArray.count);
This is the error I get:
'NSInvalidArgumentException', reason: 'Unable to parse the format string "SUBQUERY(inputArray, $object, $object.first_name CONTAINS[c] J"'
This is a basic example for testing. The real-case scenario is that I have an array of objects (Person or whatever) and I want to filter that array by certain fields within the objects ie first_name. As the user types we will filter a visual list based on what they type - so typing "J" would yield 2 results, but then when they type "Jo" only "John" appears on the list.
What am I doing wrong?
EDIT
Still doesn't seem to be working. Updated code:
DOVisitor *vi = [inputArray objectAtIndex:0];
NSLog(#"NAME: %#",vi.first_name);
NSPredicate *firstNamePredicate=[NSPredicate predicateWithFormat:#"first_name LIKE[cd] %#", #"Jo"];
NSPredicate *lastNamePredicate =[NSPredicate predicateWithFormat:#"last_name LIKE[cd] %#", #"Jo"];
NSPredicate *finalPredicate = [NSCompoundPredicate orPredicateWithSubpredicates : #[firstNamePredicate, lastNamePredicate]];
NSArray *filteredArray = [[inputArray filteredArrayUsingPredicate:finalPredicate]mutableCopy];
NSLog(#"Count should be 1: %d", [filteredArray count]);
I get an empty array back. However when I print the first object of the inputArray the console logs "John"
EDIT
Using CONTAINS instead of LIKE does the trick
You don't need a subquery for this, this is a very basic filter.
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"first_name CONTAINS[cd] %#", #"j"];
Let us say you have Person object and you are trying to search for both firstName and lastName, then you can use:
NSPredicate *firstNamePredicate=[NSPredicate predicateWithFormat:#"firstName LIKE[cd] %#", #"Jo"];
NSPredicate *lastNamePredicate =[NSPredicate predicateWithFormat:#"lastName LIKE[cd] %#", #"Jo"];
NSPredicate *finalPredicate = [NSCompoundPredicate orPredicateWithSubpredicates : #[firstNamePredicate, lastNamePredicate]];
The final Predicate is generated by oring the previous predicates. So even if Jo is present in firstName or lastName, that Person object will pass the predicate test.
Edit:
Get filtered objects with above predicate
NSArray *filteredArray = [inputArray filteredArrayUsingPredicate:finalPredicate];
I have a app in which i want searching. I have a array resultArray which contain all the things which display like
Book*bookObj=[resultArray objectAtIndex.indexPath.row];
NSString*test=bookObj.title;
I want to perform search on title item in resultArray if search text enter in textfield matches with title with any of the arrays then copy those all array values in testArray.
Use this as :
NSMutableArray *searchDataMA = [NSMutableArray new];
for (int i = 0; i < resultArray.count; i++) {
Book *bookObj=[resultArray objectAtIndex:i];
NSString*test=bookObj.title;
NSRange rangeValue1 = [test rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (rangeValue1.length != 0) {
if (![resultArray containsObject:test]) {
[searchDataMA addObject:test];
}
}
}
You have to take another array for this. this will add your object
for (Book * bookObj in resultArray) {
NSString *strName=[[bookObj.title]lowercaseString];
if ([strName rangeOfString:searchText].location !=NSNotFound) {
[arrTemp addObject:bookObj];
}
}
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate is exactly the function that you want. It will return a new array with only the elements that pass the test in the NSPredicate object.
For example:
NSArray *newArray = [oldArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Book *evaluatedObject, NSDictionary *bindings) {
//Do whatever logic you want to in here
return [evaluatedObject.title isEqualToString:theTitle];
}];
It works for me try this:
NSArray *fruits = [NSArray arrayWithObjects:#"Apple", #"Crabapple", #"Watermelon", #"Lemon", #"Raspberry", #"Rockmelon", #"Orange", #"Lime", #"Grape", #"Kiwifruit", #"Bitter Orange", #"Manderin", nil];
NSPredicate *findMelons = [NSPredicate predicateWithFormat:#"SELF contains[cd] 'melon'"];
NSArray *melons = [fruits filteredArrayUsingPredicate:findMelons];
NSPredicate *findApple = [NSPredicate predicateWithFormat:#"SELF beginswith 'Apple'"];
NSArray *apples = [fruits filteredArrayUsingPredicate:findApple];
NSPredicate *findRNotMelons = [NSPredicate predicateWithFormat:#"SELF beginswith 'R' AND NOT SELF contains[cd] 'melon'"];
NSArray *rNotMelons = [fruits filteredArrayUsingPredicate:findRNotMelons];
NSLog(#"Fruits: %#", fruits);
NSLog(#"Melons: %#", melons);
NSLog(#"Apples: %#", apples);
NSLog(#"RNotMelons: %#", rNotMelons);
Predicates also have more condition functions, some of which I have only touched on here:
beginswith : matches anything that begins with the supplied condition
contains : matches anything that contains the supplied condition
endswith : the opposite of begins with
like : the wildcard condition, similar to its SQL counterpart. Matches anything that fits the wildcard condition
matches : a regular expression matching condition. Beware: quite intense to run
The syntax also contains the following other function, predicates and operations:
AND (&&), OR (||), NOT (!)
ANY, ALL, NONE, IN
FALSE, TRUE, NULL, SELF
Still if don't understand take a look at this link;
Useful link
I have a plist working with a search display controller which contains an array of dictionaries with some data members like.
<root> (array)
<"Item 0"> (dictionary)
<"Name"></"Name" (String)
<"Work"></"Work"> (String)
<"Age"></"Work"> (Number)
</"Item 0">
<"Item 1">
....
</"Item 1">
</root>
I would like to use an NSPredicate to filter all the names that match with the search criteria. For example searching "an" for all names will yield "Sandy" and "Alexander."
So far I've tried things like:
NSPredicate *p = [NSPredicate predicateWithFormat:#"Name == %#",
filterText];
Results = [data filteredArrayUsingPredicate:p];
Any ideas? Thanks.
Use CONTAINS in NSPredicate
Below code gives case sensitive search
NSPredicate *p = [NSPredicate predicateWithFormat:#"Name CONTAINS %#",
filterText];
Results = [yourPlistDataArray filteredArrayUsingPredicate:p];
Below code gives case insensitive search
NSPredicate *p = [NSPredicate predicateWithFormat:#"ANY Name CONTAINS %#",
filterText];
Results = [yourPlistDataArray filteredArrayUsingPredicate:p];
EDIT : Refer more here
this can show you the very generic type of the searching in any NSArray. it is adjusted to your NSDictionary items currently, but you can create even more complex conditions here to filter it.
NSArray *originalArray = ...;
NSString *searchText = ...; // this is a parameter only, it can be set freely
NSArray *_filteredArray = [originalArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSDictionary *_dataRow = (NSDictionary *)evaluatedObject;
return ([[[_dataRow valueForKey:#"Name"] lowercaseString] rangeOfString:[searchText lowercaseString]].location != NSNotFound);
}]];
NSLog (#"%#", _filteredArray);