NSMutableArray search - iphone

I have a UISearchBar and I am performing a search on an array and displaying result. The search works perfect for the first letter but the application crashes when I add a letter in search or even when I press backspace. Here is the code I am using:
for (NSString *sTemp in arrCatSearch)
{
NSRange titleResultsRange = [sTemp rangeOfString:strSearch options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[searchArray addObject:[catalog.catalogItems objectAtIndex:i]];
i++;
}
The application crashes in the NSRange line.

I am using NSRange like :
NSRange result = [searchString rangeOfString:searchBar.text options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)];
in search bar's delegate methods
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText

Searching an array for results should be done with the NSPredicate class:
NSPredicate *filterPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#",searchBar.text];
//filter array based on the predicate
searchArray = [arrCatSearch filteredArrayUsingPredicate:filterPredicate];

I think this should give you a better result.
if ([sTemp rangeOfString: strSearch options: NSCaseInsensitiveSearch].location != NSNotFound)
{
if (![searchArray containsObject: [catalog.catalogItems objectAtIndex: i]])
{
[searchArray addObject: [catalog.catalogItems objectAtIndex: i]];
}
}

Related

Searching the initial letter of a word using searchBar

In my app, i have a search bar in my contact list page tableview. now my code searches the list based on any letter even if the search text is at the middle of the firstname or lastname. But i want it to search only from the beginning. For example., the word "sh" should pull only "Shiva", "Sheela", etc., but not "sathish", "suresh" etc., can anyone help me on this?
and my code is
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText
{
//---if there is something to search for---
if ([searchText length] > 0)
{
isSearchOn = YES;
canSelectRow = YES;
self.ContactTableview.scrollEnabled = YES;
searchTextValue = searchText;
[searchResult removeAllObjects];
for (NSString *str in ContactArray)
{
NSRange range = [str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(range.location != NSNotFound)
{
if(range.length > 0)//that is we are checking only the start of the names.
{
[searchResult addObject:str];
}
}
}
}
else
{
//---nothing to search---
isSearchOn = NO;
canSelectRow = NO;
self.ContactTableview.scrollEnabled = YES;
//SearchBar.showsCancelButton = NO;
[TitleBarLabel setText:#"All Contacts"];
}
[ContactTableview reloadData];
}
try with predicates,in below code replace your values.
NSPredicate *p = [NSPredicate predicateWithFormat:#"SELF BEGINSWITH[cd] %#",#"A"];
NSArray *a = [NSArray arrayWithObjects:#"AhfjA ", #"test1", #"Test", #"AntA", nil];
NSArray *b = [a filteredArrayUsingPredicate:p];
NSLog(#"--%#",b);
O/P:-
(
AntA,
AntA
)

Sort an NSString

i have an iOS application witch have a search bar and a UITableView. when i click in the search bar for example "ta", the web services return to me all the words witch contain "at",
for example "beta","mota","at work","ebebebatbcbcb" , i would like to have just the words witch begin with "at", not all the words witch contain "at".
Thanks for your answers.
try this:
-(NSMutableArray *)array:(NSMutableArray *)array withstart:(NSString *)string{
NSPredicate *sPredicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#",string];
[array filterUsingPredicate:sPredicate];
return array;
}
Or other way:
NSString *prefix = #"at";
NSArray *final_array=[array objectsAtIndexes:[array indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop)
{
return [obj hasPrefix:prefix];
}]];
NSPredicate is the way to go:
NSString *searchTerm = #"ta";
NSArray *matchingKeywords = [result filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF beginswith[cd] %#",searchTerm]];
Heres a simple answer
NSString *prefix = #"at";
[array objectsAtIndexes:[array indexesOfObjectsPassingTest:^BOOL(NSString *string, NSUInteger idx, BOOL *stop) {
return [string hasPrefix:prefix];
}]];
Sounds like a job for NSPredicate!

Dynamic display of list while using search bar in ipad

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

UITableView / UISearchBar Returns Incorrect Results

I am attempting to implement searching in a UITableView. When searching, it appears that the correct number of results are returned, but I am receiving entries from the original stories array in the results, rather than searchResults. I can see that the searchResults array should be the data source, but haven't been able to figure out after tons of searching quite how to pull it off with an array of NSDictionaries. Any help is appreciated.
- (void)handleSearchForTerm:(NSString *)searchTerm {
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release], array = nil;
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSDictionary *currentItem in [self stories])
{
if ([[currentItem objectForKey:#"title"] rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentItem];
}
}
}
}
[tableView isEqual:self.searchDisplayController.searchResultsTableView] is also another alternative to making and managing your own BOOL isFiltering; variable
use NSPredicate for filtering
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"self.title MATCHES %#",searchTerm];
Suppose that your original array is "originalArray" so to get the filtered array use this make two more global variables
NSArray* filteredArray;
BOOL isFiltering;
Now in search bar delegate method do following
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"self.title MATCHES %#",searchTerm];
filteredArray = [[originalArray filteredArrayUsingPredicate:predicate] retain];
}
Now you need to change l'll bit your table view delegate and data source, .... for all the places where you are using
NSDictionary *currentString = [originalArray objectAtIndex:indexPath.row];
use following
NSDictionary *currentString;
if(isFiltering)
currentString = [originalArray objectAtIndex:indexPath.row];
else
currentString = [filteredArray objectAtIndex:indexPath.row];

Search is only matching words at the beginning

In one of the code examples from Apple, they give an example of searching:
for (Person *person in personsOfInterest)
{
NSComparisonResult nameResult = [person.name compare:searchText
options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)
range:NSMakeRange(0, [searchText length])];
if (nameResult == NSOrderedSame)
{
[self.filteredListContent addObject:person];
}
}
Unfortunately, this search will only match the text at the start. If you search for "John", it will match "John Smith" and "Johnny Rotten" but not "Peach John" or "The John".
Is there any way to change it so it finds the search text anywhere in the name? Thanks.
Try using rangeOfString:options: instead:
for (Person *person in personsOfInterest) {
NSRange r = [person.name rangeOfString:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)];
if (r.location != NSNotFound)
{
[self.filteredListContent addObject:person];
}
}
Another way you could accomplish this is by using an NSPredicate:
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", searchText];
//the c and d options are for case and diacritic insensitivity
//now you have to do some dancing, because it looks like self.filteredListContent is an NSMutableArray:
self.filteredListContent = [[[personsOfInterest filteredArrayUsingPredicate:namePredicate] mutableCopy] autorelease];
//OR YOU CAN DO THIS:
[self.filteredListContent addObjectsFromArray:[personsOfInterest filteredArrayUsingPredicate:namePredicate]];
-[NSString rangeOfString:options:] and friends are what you want. It returns:
"An NSRange structure giving the location and length in the receiver of the first occurrence of aString, modulo the options in mask. Returns {NSNotFound, 0} if aString is not found or is empty (#"")."