I am trying to replace text within an array and for some reason the code doesn't work, despite no line alert by Xcode, it causes it to crash.
i.e. "name, 2013"
stripping ", 2013"
to result in
"name"
What am I doing wrong, for the life of me I can't work it out and desperately need help on this?
The specific line in question is "case ITSectionTypeAuthor:"
- (void)setUpDataByType:(ITSectionType) type andFilter:(NSString *)filter {
self.type = type;
self.filter = (filter)? filter : #"";
[self.sections removeAllObjects];
NSPredicate *predicate = nil;
NSString *descriptorKey = #"genus";
NSArray *rowData = [[ITData sharedObject] animals]; //coming form singleton
//generate predicate
switch (self.type) {
case ITSectionTypeAuthor:
predicate = [NSPredicate predicateWithFormat:#"describer componentsSeparatedByString:#", "] objectAtIndex:0] LIKE %#", filter];
break;
default:
predicate = nil;
break;
}
I think the problem is in this line:
predicate = [NSPredicate predicateWithFormat:#"describer componentsSeparatedByString:#", "] objectAtIndex:0] LIKE %#", filter];
You're creating an objective-c string:
#"describer componentsSeparatedByString:#"
and then a C-string:
"] objectAtIndex:0] LIKE %#"
That can't be right, can it? I think you want:
predicate = [NSPredicate predicateWithFormat:#"describer LIKE %#", [[filter componentsSeparatedByString:#", "] objectAtIndex:0]];
Related
I'm currently filtering an NSMutableArray (neighbourUIDs) with a value, but I now want to filter the same array with a second string as well, e.g.
[predicateString appendFormat:#"SELF.neighbourhood ==[c] '%1$#' OR %#", neighbourUIDs[i], hq];
That being said, when I attempt to write the above, XCode throws me the following error:
Cannot mix positional and non-positional arguments in format string
Any idea how I can accomplish this? See current code below:
ViewController.m
NSMutableArray *neighbourUIDs = [self.currentUser valueForKey:#"neighbourhood"];
NSMutableString *predicateString = [NSMutableString string];
for (NSInteger i = 0; i < [neighbourUIDs count]; i++) {
if (i != 0) {
[predicateString appendString:#" OR "];
}
NSString *hq = #"Headquarters";
[predicateString appendFormat:#"SELF.neighbourhood ==[c] '%1$#'", neighbourUIDs[i]];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
self.closeByNeighbours = [[self.neighbourData filteredArrayUsingPredicate:predicate] mutableCopy];
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.
while implementing search functionality I need to filter array of dictionaries. I am using auto complete textfield method for search bar and am storing it into string. I can able to parse the array,But facing with below json
[{"CertProfID":"4","Name":"Dodge","Location":"loc4","City":"city4","State":"state4","Zip":"zip5","Website":"http:\/\/cnn.com","Phone":"phone4","Email":"email4"},
{"CertProfID":"5","Name":"cat","Location":"loc5","City":"city5","State":"State5","Zip":"zip5","Website":"web5","Phone":"phone5","Email":"email5"}]
Here I need to filter the dictionaries to make it finish
I tried with below code but its returning array with null values :(
NSString *substring = [NSString stringWithString:textField.text];
NSLog(#"substring %#",substring);
NSMutableArray *arr2Filt= [arraylist valueForKey:#"Name"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",substring];
filteredarr = [NSMutableArray arrayWithArray:[arr2Filt filteredArrayUsingPredicate:predicate]];
This code will solve your problem it will return an array of dictionaries
NSString *substring = [NSString stringWithString:textField.text];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Name contains[c] %#",searchString];
NSArray *filteredArry=[[arrayOfDict filteredArrayUsingPredicate:predicate] copy];
arrayOfDict is your original array of dictionaries
Swift 4.2 Version:::
let namePredicate = NSPredicate(format: "Name contains[c] %#",searchString)
let filteredArray = arrayOfDict.filter { namePredicate.evaluate(with: $0) }
print("names = \(filteredArray)")
Hope it will help you
You could use blocks instead. They are much less hand-wavy about match conditions.
NSString *substring = [NSString stringWithString:textField.text];
NSLog(#"substring %#",substring);
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject[#"Name"] containsString:substring];
}];
filteredarr = [NSMutableArray arrayWithArray:[arraylist filteredArrayUsingPredicate:predicate]];
Here one observation is that filteredArrayUsingPredicate is a method of NSArray and you are using NSMutableArray instead.
Change NSMutableArray with temporary NSArray object for predicate.
For example:
NSString *substring = [NSString stringWithString:textField.text];
NSArray *tempArray = [arraylist valueForKey:#"Name"];
// If [arraylist valueForKey:#"Name"]; line returns NSMutableArray than use below line
// NSArray *tempArray = [NSArray arrayWithArray:[arraylist valueForKey:#"Name"]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",substring];
filteredarr = [[tempArray filteredArrayUsingPredicate:predicate] mutableCopy];
Hi I know there is many any answer,
In my case I have stored values As JSON MODEL object, This is code for, using JSON MODEL
NSString *searchString = searchBar.text;
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSDictionary *temp=[evaluatedObject toDictionary];
return [temp[#"user"][#"firstName"] localizedCaseInsensitiveContainsString:searchString];
}];
filteredContentList = [NSMutableArray arrayWithArray:[searchListValue filteredArrayUsingPredicate:predicate]];
[tableViews reloadData];
searchListValue is a NSMutableArray which contains Array of json model objects.If anyone need help regarding this, just ping me
Swift version above 2.2
var customerNameDict = ["firstName":"karthi","LastName":"alagu","MiddleName":"prabhu"];
var clientNameDict = ["firstName":"Selva","LastName":"kumar","MiddleName":"m"];
var employeeNameDict = ["firstName":"karthi","LastName":"prabhu","MiddleName":"kp"];
var attributeValue = "ka";
var arrNames:Array = [customerNameDict,clientNameDict,employeeNameDict];
//var namePredicate =
// NSPredicate(format: "firstName like %#",attributeValue);
//uncomment above line to search particular word
let namePredicate =
NSPredicate(format: "firstName contains[c] %#",attributeValue);
let filteredArray = arrNames.filter { namePredicate.evaluateWithObject($0) };
print("names = ,\(filteredArray)");
More about this refer here
I have searchBar in my app,
What i want to do is when user types any character in searchBar, I want to get all the values starting with same character from my array.
Here is my code snippet i have tried but it crashes..
for (int i=0; i<[arr count]; i++) {
for(NSString *name in [[arr objectAtIndex:i] objectForKey:#"Merchant_Name"])
{
NSRange r = [name rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(r.location != NSNotFound)
{
if(r.location== 0)//that is we are checking only the start of the naames.
{
[arr addObject:name];
}
}
}
}
Shows ERROR:-[__NSDictionaryM rangeOfString:options:]: unrecognized selector sent to instance
Where i am making mistake?
Please help and thanks in advance.
EDIT:
arr = {
"Merchant_Id" = 1036;
"Merchant_Name" = "Arzoo Hotels";
"Merchant_Url" = "arzoo-hotels";
},
{
"Merchant_Id" = 1037;
"Merchant_Name" = "Ashika Mall";
"Merchant_Url" = "ashika-mall";
},
{
"Merchant_Id" = 1038;
"Merchant_Name" = "At My Doorsteps";
"Merchant_Url" = "at-my-doorsteps";
},
{
"Merchant_Id" = 1039;
"Merchant_Name" = "AVA Host";
"Merchant_Url" = "ava-host";
},
For that, you should filter your array using NSPredicate.
Edit: Using predicate and filtering is much more readable and understandable. As stated in the comment, it might be slower, but you probably won't have 10,000,000+ strings you'd like to filter through, so saving 0.00001 second probably isn't worth writing a code 10 lines longer.
Documentation here.
And here's a whole tutorial about search bar and filtering data.
A quick example to filter an array and get values that begin with 'a' or 'c':
NSMutableArray *array =
[NSMutableArray arrayWithObjects:#"Nick", #"Ben", #"Adam", #"Melissa", nil];
NSPredicate *bPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] 'a'"];
NSArray *beginWithB = [array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { #"Adam" }.
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"SELF contains[c] 'e'"];
[array filterUsingPredicate:sPredicate];
Using Below code you can do straight search
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Merchant_Name LIKE[cd] '%#' ",searchText];
NSArray *filter = [arr filteredArrayUsingPredicate:predicate];
Using Below code you can do custom search
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"Merchant_Name beginswith[c] 'a'"];
NSArray *aNames = [arr filteredArrayUsingPredicate:predicate]
-use this code
-And Set Delegate to Uitextfield.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *changedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF['Merchant_Name'] contains %#",changedText];
NSArray *filter = [arraydata filteredArrayUsingPredicate:predicate];
NSLog(#"%#%",changedText);
return YES;
}
There is NSMutableDictionary type object in arr, try this to avoid crash:
for(NSString *name in arr){
if(![name isKindOfClass:[NSString class]]){
continue;
}
NSRange r = [name rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(r.location != NSNotFound)
{
if(r.location== 0)//that is we are checking only the start of the naames.
{
[Array addObject:name];
}
}
counter++;
}
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