I am creating an app in which i am using a dictionary with quite a large number of words.Now i am creating a Search bar and that will be used to input the word which i will be looking in the dictionary.Actually this plan is accomplished with the below code but now what i want is that whenever i write a sentence say "Daddy drinks juice " then the list should display me all the permutations and combinations,i mean to say it must display all the three words individually ,then it must display sentences which will contain any of the words i entered like :- she DRINKS water,lime JUICE,mommy and DADDY and other sentences which will contain these words either individually or in combination.
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSArray *array = [dictionary objectForKey:#"Words"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"( %K contains[cd] %# ) OR ( %K contains[cd] %# ),yourfirstKey,searchText];
NSArray * filteredArray = [searchArray filteredArrayUsingPredicate:predicate];
Hope this helps
Related
I have two comma seperated NSString's & I want to remove the similar characters from first string only.
ex. str1 = 0,1,2,3
str2 = 1,2.
output -> str1 = 0,3 and str2 = 1,2.
I have one option that, seperate both the string with comma seperated values in a array. But it requires two NSArray's & apply loop and then remove the common elements, but it is very tedious job.
So I want some simple & proper solution which avoid the looping.
kindly help me to sort out this.
Try this one:
No loop is required!!!
You have got all the required APIs.
NSString *str1=#"0,1,2,3";
NSString *str2=#"1,2";
NSMutableArray *arr1=[[NSMutableArray alloc]initWithArray:[str1 componentsSeparatedByString:#","]];
[arr1 removeObjectsInArray:[str2 componentsSeparatedByString:#","]];
NSLog(#"arr1 %#",arr1);
/*
NSMutableString *finalString=[NSMutableString new];
for (NSInteger i=0; i<[arr1 count]; i++) {
NSString *str=[arr1 objectAtIndex:i];
[finalString appendString:str];
if (i!=[arr1 count]-1) {
[finalString appendString:#","];
}
}
*/
NSString *finalString=[arr1 componentsJoinedByString:#","];
NSLog(#"finalString %#",finalString);
Something like that ?
NSString *string = #"0,1,2,3";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self like '1' OR self like '2'"];
NSLog(#"%#",[[string componentsSeparatedByString:#","] filteredArrayUsingPredicate:predicate]);
id str1=#"aa,ab,ac,cd,ce,cf";
id str2=#"aa,ac,cd,cf";
//no ab and no ce
id cmps1 = [str1 componentsSeparatedByString:#","];
id cmps2 = [str2 componentsSeparatedByString:#","];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"NOT SELF IN %#", cmps2];
NSArray *final = [cmps1 filteredArrayUsingPredicate:predicate];
id str = [final componentsJoinedByString:#","];
NSLog(#"%#", str);
The only solution that I can think of would be this:
NSMutableArray* arr1 = [str1 componentsSeparatedByString:#","] mutableCopy];
NSArray* arr2 = [str2 componentsSeparatedByString:#","];
for (NSString* str in arr2) {
[arr1 removeObject:str];
}
NSString* newString1 = [arr1 componentsJoinedByString:#","];
Is this what you tried? If "str1" looks something like "1,1,2,2,2", then you might have some more work to do here to get rid of the duplicates. But that's basically it.
My Problem Scenario is like this. I have an NSMutableArray ( Every Object is Nsstring). I have a UItextField ( as Client said) for Search.
I want know how to Search String into NSMutableArray like this
if I type A into textfield only those Content come from NSMutableArray which start From A.
if I type AB into TextField only those Content Comes from NSMutableArray which is started from AB..
....
I am Trying NSRange Concept I like share Mycode
~
for (int i=0; i<[[localTotalArrayForAwailable objectForKey:#"PUNCH"] count]; i++)
{
NSString *drinkNamePuch= [[[localTotalArrayForAwailable objectForKey:#"PUNCH"] objectAtIndex:i] drinkNames];
NSRange titleResultsRange = [drinkNamePuch rangeOfString:searchText options:( NSCaseInsensitiveSearch)];
if (titleResultsRange.length>0)
{
[searchArraypuch addObject:[[localTotalArrayForAwailable objectForKey:#"PUNCH"] objectAtIndex:i]];
[copyListOfItems setValue:searchArraypuch forKey:#"PUNCH"];
}
}
~
Based on this code search not working proper as i need.
Thanks
If you're trying to find all of the strings that match your searchText from the beginning, then you should check:
if ( titleresultsRange.location == 0 )
Other than that, I am not sure what is "not working proper", you need to provide a better explanation of what your expected results are, and what your actual results are.
Do this;
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"SELF BEGINSWITH[cd] %#", searchText];
NSArray* filteredStrings = [[localTotalArrayForAwailable objectForKey:#"PUNCH"] filteredArrayUsingPredicate:predicate];
In filteredStrings you got all the strings that begins with searchText.
You might find Predicate Programming Guide helpful.
try this logic....it is working
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:#"aa",#"bbb",#"bb",#"cc",#"dd",#"ee",#"ff",#"gg",#"hh",#"ii", nil];
NSMutableArray *arrNew = [[NSMutableArray alloc]init];
NSString *strSearch = #"cccc";
int k = strSearch.length;
for (int i=0; i<[arr count]; i++) {
for (int j=0; j<k; j++) {
if (k<=[[arr objectAtIndex:i] length]) {
if ([strSearch characterAtIndex:j] != [[arr objectAtIndex:i]characterAtIndex:j]) {
break;
}
else if(j == k-1){
[arrNew addObject:[arr objectAtIndex:i]];
}
}
}
}
NSLog(#"%#",[arrNew description]);
You can use these methods, which are provided by NSArray/NSMutableArray:
In NSArray see section "Finding Objects in an Array" for filtering methods starting with "indexesOfObjects...", e.g. indexesOfObjectsPassingTest:
In NSArray see section "Deriving New Arrays" for the method filteredArrayUsingPredicate:
In NSMutableArray there is a method filterUsingPredicate:
For narrowing the results you can continue applying the filtering consecutively to the filtered arrays or index sets.
Example with indexesOfObjectsPassingTest: using a block:
NSArray *strings = [NSArray arrayWithObjects:#"A", #"a", #"aB", #"AbC", #"Bag", #"Babc", #"baCK", #"", #"dba", nil];
NSString *searchString = #"Ab";
BOOL (^startsWithPredicate)(id, NSUInteger, BOOL*) = ^BOOL (id obj, NSUInteger idx, BOOL *stop) {
NSString *string = (NSString *) obj;
NSRange range = [string rangeOfString:searchString options:NSCaseInsensitiveSearch];
return (range.location == 0);
};
NSIndexSet *indexSet = [strings indexesOfObjectsPassingTest:startsWithPredicate];
NSLog(#"Strings found: %#", [strings objectsAtIndexes:indexSet]);
Output:
Strings found: (
aB,
AbC
)
Okay so I have been working through an example that closely matches what I am trying to achive, the sole difference being that in the example he is directly calling from his database the data he needs to be sectioned etc. Where as I already have a sorted NSArray.
This is the tutorial I am working off - iPhone Development: Creating Native Contacts like screen
I have created a Method that is capturing each entry in the NSArray and putting these results into a alpha based NSDictionary (so their will be a NSDictionary for A,B,C... etc)
here is my method.
//method to sort array and split for use with uitableview Index
- (IBAction)startSortingTheArray:(NSMutableArray *)arrayData
{
//Sort incoming array alphabetically
//sortedArray = [arrayData sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
[self setSortedArray:[arrayData sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]];
arrayOfCharacters = [[NSMutableArray alloc]init];
objectsForCharacters = [[NSMutableDictionary alloc]init];
for(char c='A';c<='Z';c++)
{
if([sortedArray count] >0)
{
[arrayOfCharacters addObject:[NSString stringWithFormat:#"%c",c]];
[objectsForCharacters setObject:sortedArray forKey:[NSString stringWithFormat:#"%c",c]];
NSLog(#"%#", objectsForCharacters);
}
[sortedArray release];
//Reloads data in table
[self.tableView reloadData];
}
}
This is putting every value into every alpha section, I am hoping someone can help me with making it so that only alpha sections are established if there is a value in the array for it.. then only loading those values into each section, not every section.
This piece of code will do just that and will be much more efficient than filtering the array once for each letter.
//Sort incoming array alphabetically so that each sub-array will also be sorted.
NSArray *sortedArray = [arrayData sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
// Dictionary will hold our sub-arrays
NSMutableDictionary *arraysByLetter = [NSMutableDictionary dictionary];
// Iterate over all the values in our sorted array
for (NSString *value in sortedArray) {
// Get the first letter and its associated array from the dictionary.
// If the dictionary does not exist create one and associate it with the letter.
NSString *firstLetter = [value substringWithRange:NSMakeRange(0, 1)];
NSMutableArray *arrayForLetter = [arraysByLetter objectForKey:firstLetter];
if (arrayForLetter == nil) {
arrayForLetter = [NSMutableArray array];
[arraysByLetter setObject:arrayForLetter forKey:firstLetter];
}
// Add the value to the array for this letter
[arrayForLetter addObject:value];
}
// arraysByLetter will contain the result you expect
NSLog(#"Dictionary: %#", arraysByLetter);
Note that arraysByLetter is a dictionary that contains one array per "first letter" that exists in your initial data.
--- Added on 2011-09-23 ---
[sortedArray removeAllObjects];
NSArray *sortedKeys = [arraysByLetter.allKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
for (NSString *key in sortedKeys) {
[sortedArray addObject:key];
[sortedArray addObjectsFromArray: [arraysByLetter objectForKey:key]];
}
NSLog(#"Sorted Array: %#", sortedArray);
The output is the following:
C,
Computer,
H,
Helene,
Hello,
J,
Jules,
W,
World
Looks like you need to filter sortedArray with a predicate for each letter. Something like this...
for(char c='A';c<='Z';c++) {
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF beginswith[c] '%c'", c];
NSArray *objectsBeginningWithCurrentLetter = [array filteredArrayUsingPredicate:predicate];
if([sortedArray count] >0)
{
[arrayOfCharacters addObject:[NSString stringWithFormat:#"%c",c]];
if ([objectsBeginningWithCurrentLetter count] > 0) {
[objectsForCharacters setObject:objectsBeginningWithCurrentLetter forKey:[NSString stringWithFormat:#"%c",c]];
NSLog(#"%#", objectsForCharacters);
}
}
[sortedArray release];
//Reloads data in table
[self.tableView reloadData];
}
I've been playing around with a search facility for my application table view for a while now trying to get it working but i keep getting the same error in my console.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' [NSCFDictionary rangeOfString:options:]: unrecognized selector sent to instance
I believe that this following section may be the problem I have tried passing some NSLog entries inside the if statement and it seems to get through it but the problem is when I click on the search bar and starting typing, the first letter I type calls the error and cancels my app.
Here is where the problem is
In View Will Appear "Food" Array is initialized as below:
NSString *myDBnew =#"/Users/taxsmart/Documents/rw3app.sql";
database = [[Sqlite alloc] init];
[database open:myDBnew];
NSString *quer = [NSString stringWithFormat:#"Select category from foodcat"];
Food = [database executeQuery:quer];
//[database executeNonQuery:quer];
[database close];
Search bar delegate method where error is encountered:
(void) searchTableView
{
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
// [searchArray addObjectsFromArray:Food];
for(NSDictionary *dictionary in Food)
{
NSString temp1 = [dictionary objectForKey:#"category"];
[searchArray addObject:temp1];
}
for (NSString *sTemp in searchArray)
{
NSLog(#"Value: %#",NSStringFromClass([sTemp class]));
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
What should I do?
Please Help.
Please Suggest
Thanks
It looks that result of database query (Food) is dictionary that contains dictionary. This code:
for(NSDictionary *dictionary in Food)
{
NSString temp1 = [dictionary objectForKey:#"category"];
[searchArray addObject:temp1];
}
can be replaced with:
for(NSDictionary *dictionary in Food)
{
NSObject *ob = [dictionary objectForKey:#"category"];
if([ob isKindOfClass: [NSString class]])
{
[searchArray addObject:ob];
}
else if([ob isKindOfClass: [NSDictionary class]])
{
NSDictonary *dic1 = (NSDictionary*)ob;
// ... at this point you can get the string for desired dictionary key
// or you can ignore it
}
}
With this code we can be sure that only strings are put into searchArray.
If you want to make full tree parsing for desired key 'category' then you should make some recursive function to search the dictionary.
You can dump Food variable to console to see at which leaf is actually the result you are looking for. Put the break-point and into console type 'po Food'.
Appears that there is an NSDictionary in your dataArray.
Add an
NSLog(#"%#",NSStringFromClass([description class]]));
To see which classes your dataArray contains.
So I'm having trouble implementing a search bar in my app.
The methods find the filtered items but for some reason they won't show up in my tableview.
I think it has something to do with adding the objects to the filteredListContentArray.
What object should I be adding for this to work.
Here's my code:
{
[self.filteredListContent removeAllObjects]; // First clear the filtered array.
for (NSDictionary *dictionary in tableDataSource)
{
NSString *testString = [dictionary valueForKey:#"Title"];
NSLog(#"String list to be Searched is %#", testString);
//NSLog(#"Contents of list are %#", testString);
NSComparisonResult result = [testString compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
//NSObject *filteredObject = [dictionary objectForKey:#"Title"];
if (result == NSOrderedSame)
{
NSLog(#":-)");
NSLog(#"Resulted object is %#", [dictionary valueForKey:#"Title"]);
[self.filteredListContent addObject:dictionary];
}
else
{
NSLog(#":-(");
}
}
NSLog(#"Contents of Filtered list are %#", self.filteredListContent);}
That last NSLog reads (null) every time, but the NSLog Above it always shows the correct filtered items.
where do you allocate memory for your filteredListContent? and there is tableDataSource array. do you fill your table from filteredListContent or from tableFataSource array? also you can try to print to console [filteredListContent description];