my application is comparing strings of requests sent to a function, like -(void)sendSearchRequest:(NSString *)request sport:(NSString *)sport location:(NSString *)location. I'm setting the request to 'Kevin', the sport to 'Baseball' and the location to 'Wellston'.
Then, I'm comparing it against an object whose request is 'Kevin', sport is 'Basketball', and location is 'Wellston'. The sport should return false, but it isn't. Whats going on?
for (Athlete *athlete in self.athletes) {
NSComparisonResult result = [[athlete name] compare:request options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [request length])];
NSComparisonResult sportCompare = [[athlete sport] compare:sport options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [sport length])];
NSComparisonResult locationCompare = [location compare:self.cityName options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [self.cityName length])];
NSLog(#"Location: %#", location);
NSLog(#"Name: %#", request);
NSLog(#"Sport: %#", sport);
if (result == NSOrderedSame && sportCompare == NSOrderedSame && locationCompare == NSOrderedSame) {
[self.filteredArray addObject:athlete];
}
}
Notes:
* I have to take account for user error. These variables are being passed from a UITextField, so if a user enters 'Wellston, OK' but the object's city is 'Wellston', it won't work
If you want to know whether two strings are the same, why are you using NSComparisonResult? That makes no sense at all. It is for sorting. Just use isEqualToString: - that's what it's for.
Or for more a more sophisticated notion of equality, you can implement an anchored substring search. You can make that case-insensitive and diacritic-insensitive. Thus you can determine whether one string starts with another, for example.
Related
I have a tableview that filters based on a search bar. This works well as long as the search begins with the same characters as the cell text.
I would like to be able to search any part of the cell text, even in the middle. For example. If the cell text is "Jon Bon Jovi" I would like it to still come up if the user types "Bon Jovi" or even just "Jovi" into the search bar.
My current code is below:
for (NSDictionary *item in listItems)
{
if ([scope isEqualToString:#"All"] || [[item objectForKey:#"type"]
isEqualToString:scope] || scope == nil)
{
NSComparisonResult result = [[item objectForKey:#"name"]
compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)
range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[filteredListItems addObject:item];
}
}
}
Any help would be awesome. Thank you all!
Instead of using -compare:options:range: (which just sorts your search string relative to your item's name), consider looking at -rangeOfString:options: - that will actually search the entire item name for your search string. You would replace the inner body of your if statement with something like:
NSStringCompareOptions opts = (NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch);
NSRange resultRange = [[item objectForKey:#"name"] rangeOfString:searchText
options:opts];
if (resultRange.location != NSNotFound) {
[filteredListItems addObject:item];
}
I have the method below for filtering some results:
Currently it does this:
array: alpha, apple, aries, bravo
type a:
alpha
apple
aries
type l (now al)
alpha
I wanted to do this:
new search:
type p=
alPha
apple
below is the code
thank you kindly in advance
-(void) filterResults:(NSString *)searchText{
NSMutableArray *test = [NSMutableArray arrayWithArray:self.listContent];
[self.filteredListContent removeAllObjects]; // First clear the filtered array.
for (int i=0; i<[test count]; i++) {
NSString *stringResult = [test objectAtIndex:i];
NSComparisonResult result = [stringResult compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame){
[self.filteredListContent addObject:stringResult];
}
}
[self.filteredListContent sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];//sort alphabetically
NSLog(#"filtered results = %#",self.filteredListContent);
}
To find the letter anywhere in your string, replace this:
NSComparisonResult result = [stringResult compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame){
[self.filteredListContent addObject:stringResult];
}
with this:
NSRange range = [stringResult rangeOfString:searchText];
if (range.location != NSNotFound) {
[self.filteredListContent addObject:stringResult];
}
Note that it will have to find all of the characters, in order.
If you want to find any of the characters, then use rangeOfCharacterFromSet:.
Try this one.
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"SELF beginswith '%#'", searchText]];
self.filteredListContent = [self.listContent filteredArrayUsingPredicate:predicate];
Hope this helps you.
This is my current search code.
-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope {
[filteredList removeAllObjects];
for(Location *item in list)
{
NSRange result = [item.title rangeOfString:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];
if(result.location != NSNotFound)
{
[filteredList addObject:item];
}
}
}
How would I change this to match any part of the title and not just the start.
Example:
At the moment if I search for 'Las', 'Las Vegas' will appear in the list, but when I search for 'Vegas' it does not.
I want the search term 'Vegas' to come back with 'Las Vegas'
Thanks,
Ashley
Use rangeOfString:options: instead of rangeOfString:options:range:. It is the range parameter that restricts the search to the beginning of the string.
Or if for some reason you want to use rangeOfString:options:range: then use this as range: NSMakeRange(0, [item.title length])
Yes, yes. Shame on me. I am trying to draw in UIView and my code is:
NSString *str;
if(kmObj.metal!=#"" && kmObj.metalName2!=#"" && kmObj.metalname3!=#"")
{
str=[NSString stringWithFormat:#"%# + %# + %#",kmObj.metal,kmObj.metalName2,kmObj.metalname3];
}
if(kmObj.metal!=#"" && kmObj.metalName2!=#"" && kmObj.metalname3==#"")
{
str=[NSString stringWithFormat:#"%# + %#",kmObj.metal,kmObj.metalName2];
}
if(kmObj.metal!=#"" && kmObj.metalName2==#"" && kmObj.metalname3==#"")
{
str=[NSString stringWithFormat:#"%#",kmObj.metal];
}
[str drawAtPoint:CGPointMake(10.0,234.0)
forWidth:200
withFont:[UIFont systemFontOfSize:20.0]
minFontSize:20.0
actualFontSize:NULL
lineBreakMode:UILineBreakModeTailTruncation
baselineAdjustment:UIBaselineAdjustmentAlignBaselines];
So, this code suppose to check if the Object contains more than one metal name record. If so, than it has to format string to form: Au+Ag+Cu ... My problem is that in output draw I can't get rid of the + signs where I don't need them. Is there something wrong in my if statement?
Instead of if (string != #""), use ![string isEqualToString:#""] or perhaps ([string length] > 0). You need to make sure you are performing a value comparison, not a pointer comparison.
Anyway, I would write code like this:
NSString *outputString = #"";
if ([firstString length] > 0) {
outputString = [outputString stringByAppendingString:firstString];
}
if ([secondString length] > 0) {
outputString = [outputString stringByAppendingFormat:#" + %#", secondString];
}
if ([thirdString length] > 0) {
outputString = [outputString stringByAppendingFormat:#" + %#", thirdString];
}
With this technique, you check each string individually, and only include a plus sign when you know another valid string will follow it.
String comparisons should take the form: [stringA isEqualToString:stringB]
From the docs: When you know both objects are strings, this method is a faster way to check equality than isEqual:
Plus, == for strings is weird anyways - they are non-primitives and you're wanting a value comparison.
Also, you should take into account the possibility of having nil and/or [NSNull null] values (depending on where these values are sourced). Your current test of whether or not they are equal to empty strings doesn't take this into account.
Did you mean that you don't want the "+" sign? Then don't put it in your NSString.
So instead of
str = [NSString stringWithFormat:#"%# + %# + %#",kmObj.metal,kmObj.metalName2,kmObj.metalname3];
do
str = [NSString stringWithFormat:#"%# %# %#",kmObj.metal,kmObj.metalName2,kmObj.metalname3];
also use [kmObj.metal isEqualToString:#""] for your string comparison
i have a Searchbar with a Scopebar in my RootViewController. If I am searching for the items it's working very fine, also if I searching in a Scope Range. But how is it possible to show Scope Results, if no Searchtext was given from the User?
A Code Sample would be very fine.
Here is the Code which filter after the User set Text into the Seachbar.
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.filteredContent removeAllObjects]; // First clear the filtered array.
for (test *new in tabelle)
{
//cat1
if ([scope isEqualToString:#"cat1"] && [new.Location isEqualToString:#"cat1"])
{
NSComparisonResult result = [new.TText compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[self.filteredContent addObject:new];
}
}
//cat2
if ([scope isEqualToString:#"cat2"] && [new.Location isEqualToString:#"cat2"])
{
NSComparisonResult result = [new.TText compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[self.filteredContent addObject:new];
}
}
//all
if ([scope isEqualToString:#"Alle"])
{
NSComparisonResult result = [new.TText compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[self.filteredContent addObject:new];
}
}
}
}
I want results without any typed letter in the Searchbar
Like this image but without the typed in letter: http://edumobile.org/iphone/wp-content/uploads/2010/03/search.jpg