Sort an NSString - iphone

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!

Related

NSPredicate of NSArray in NSDictionary

My Array
(
{id:1,data:(#"macbook",#"mac mini")},
{id:2,data:(#"ipad",#"ipod")},
{id:3,data:(#"macbook",#"ipod")}
)
I have a predicate
NSString *text = #"mac";
[NSPredicate predicateWithFormat:#"(data contains[cd] %#)",text];
[array filteredArrayUsingPredicate:predicate];
but it doesn't loop over my array inside my dictionary
(my result should be an array containing 2 objects with id 1 and 3)
NSString* text = #"mac" ;
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"any data contains[cd] %#",text] ;
NSArray* filteredArray = [theArray filteredArrayUsingPredicate:predicate] ;
I personally find NSPredicate formats very error prone.
You may consider using a block in order to filter your NSArray
NSString * filterString = #"mac";
NSIndexSet * indexes = [array indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
NSArray * entry = obj[#"data"];
for (NSString * value in entry)
if ([value rangeOfString:filterString].location != NSNotFound)
return YES;
return NO;
}];
NSArray * filteredArray = [array objectsAtIndexes:indexes];
It's definitely longer and more verbose, but I find it definitely easier to read and debug.

Search String into NSArray based on charcters order?

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
)

What's the easiest way to remove empty NSStrings from an NSArray?

In PHP it's one line of code:
$array_without_empty_strs = array_filter($array_with_empty_strs);
What's the objective C equivalent?
UPDATE - Added the following test code to illustrate the use of Nikolai Ruhe's solution:
// SOLUTION Test Code
NSMutableArray *myArray = [[NSMutableArray alloc] init ];
[myArray addObject:[NSNumber numberWithInt:5]];
[myArray addObject:#""];
[myArray addObject:#"test"];
NSLog(#"%#", myArray);
[myArray removeObject:#""];
NSLog(#"%#", myArray);
// SOLUTION Test Code Output
2012-07-12 08:18:16.271 Calculator[1527:f803] (
5,
"",
test
)
2012-07-12 08:18:16.273 Calculator[1527:f803] (
5,
test
)
It's even more simple:
[mutableArrayOfStrings removeObject:#""];
If your array is not mutable you have to create a mutableCopy before.
removeObject: removes all objects from an array that return YES from isEqual:.
NSArray *noEmptyStrings = [maybeEmptyStrings filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:#"length > 0"]];
we can use NSPredicate
here my code
NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(id str, NSDictionary *unused) {
return ![str isEqualToString:#""];
}];
NSArray *filtered = [yourArray filteredArrayUsingPredicate:pred];
Look at this question, which is almost exactly the same as yours.
I use this method for non-string (object) cases that don't work with NSPredicate
Where array is NSMutableArray
- (void) clearArrayOut
{
for (int j=[array count]-1; j>=0; j--)
if ([[array objectAtIndex:j] length] == 0)
[array removeObjectAtIndex:j];
}
And I totally just stole this from rob mayoff's beautiful answer on my question NSPredicate instead of loop to filter an array of objects
Here's an alternate method that is more flexible even than using a predicate.
NSArray* filteredArray = [arrayToFilter objectsWithIndexes:
[arrayToFilter indexesOfObjectsPassingTest:
^((id obj, NSUInteger idx, BOOL *stop)
{
return [obj length] > 0;
}]];

How to search in NSArray?

I am having an array like fallowing,
NSArray*array = [NSArray arrayWithObjects:#"1.1 something", #"1.2 something else", #"1.3 out of left field", #"1.4 yet another!", nil];
Now,i am having the string like fallowing,
NSString*str = #"1.3";
Now i will send the str .Then it needs to find that str in array and it need to return the index of object where that text found.Means i need index 2 has to come as output.Can anyone share the code please.Thanks in advance.
Here is an example using blocks, notice the method: hasPrefix:
NSArray *array = [NSArray arrayWithObjects:#"1.1 problem1", #"1.2 problem2", #"1.3 problem3", #"1.4 problem4", nil];
NSString *str = #"1.3";
NSUInteger index = [array indexOfObjectPassingTest:
^(id obj, NSUInteger idx, BOOL *stop) {
return [obj hasPrefix:str];
}];
NSLog(#"index: %lu", index);
NSLog output:
index: 2
First a comment,
NSString *str = 1.3;
does not create an NSString object. You should instead have
NSString *str = #"1.3";
To search the NSArray, you will either have to change the string to the exact string in the array or search the NSString as well. For the former, simply do
float num = 1.3;
NSString *str = [NSString stringWithFormat:#"%.1f problem%d",num,(num*10)%10];
[array indexOfObject:str];
You can get fancier using NSPredicates as well.
Try
NSString *searchString = [str stringByAppendingFormat: #" problem%#", [str substringFromIndex: 2]];
NSUInteger index = [array indexOfObject: searchString];
Or (because you somehow like oneliners):
[array indexOfObject: [[array filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: #"SELF beginswith %#", str]] objectAtIndex: 0]];
The simplest way is to enumerate through values of array and check substrings:
NSArray *array = [NSArray arrayWithObjects: #"1.1 something", #"1.2 something else", #"1.3 out of left field", #"1.4 yet another!", nil];
NSString *str = #"1.33";
int i = -1;
int index = -1;
for (NSString *arrayString in array) {
i++;
if ([arrayString rangeOfString: str].location != NSNotFound) {
index = i;
break;
}
}
NSLog(#"Index: %d", index);
Not optimal but will work.

How retrieve an index of an NSArray using a NSPredicate?

I would know how retrieve an index of an NSArray using a NSPredicate ?
NSArray *array = [NSArray arrayWithObjects:
#"New-York City",
#"Washington DC",
#"Los Angeles",
#"Detroit",
nil];
Which kind of method should I use in order to get the index of "Los Angles" by giving only a NSString?
NB: #"Los An" or #"geles" should return the same index.
Using NSPredicate you can get array of strings that contain your search string (it seems there's no built-in method to get just element indexes):
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS[cd] %#", searchString];
NSArray *filteredArray = [array filteredArrayUsingPredicate: predicate];
You can get only indexes using indexesOfObjectsPassingTest: method:
NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
NSString *s = (NSString*)obj;
NSRange range = [s rangeOfString: searchString];
return range.location != NSNotFound;
}];
If you want to get just one element containing your string you can use similar indexOfObjectPassingTest: method for that.
You should be able to do this with blocks. Below is a snippet (I don't have a compiler handy so pls excuse any typos):
NSArray *array = [NSArray arrayWithObjects:
#"New-York City",
#"Washington DC",
#"Los Angeles",
#"Detroit",
nil];
NSString *matchCity = #"Los";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#", matchCity];
NSUInteger index = [self.array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [predicate evaluateWithObject:obj];
}];
Essentially you can use the indexOfObjectPassingTest: method. This takes a block (code following the "^") and returns the index for the first object that matches your predicate (or NSNotFound if no match exists). The block iterates through each object in the array until either a match is found (at which point it returns the index) or no match is found (at which point it returns NSNotFound). Here is a link to block programming that can help you understand the logic within the block:
https://developer.apple.com/library/ios/featuredarticles/Short_Practical_Guide_Blocks/
Found an alternative approach helpful where the search is more complex as it allows predicate to be used to find object then object to find index:
-(NSIndexPath*) indexPathForSelectedCountry{
NSUInteger indexToCountry = 0;
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"isoCode = %#",self.selectedCountry.isoCode];
NSArray * selectedObject = [self.countryList filteredArrayUsingPredicate:predicate];
if (selectedObject){
if (self.searchDisplayController.isActive){
indexToCountry = [self.searchResults indexOfObject:selectedObject[0]];
}else{
indexToCountry = [self.countryList indexOfObject:selectedObject[0]];
}
}
return [NSIndexPath indexPathForRow:indexToCountry inSection:0];
}
I would do this..
NSString * stringToCompare = #"geles";
int foundInIndex;
for ( int i=0; i<[array count]; i++ ){
NSString * tryString = [[array objectAtIndex:i] description];
if ([tryString rangeOfString:stringToCompare].location == NSNotFound) {
// no match
} else {
//match found
foundInIndex = i;
}
}// end for loop
Based on #Louie answer, instead of using for loop i had used enumeration block which worked for me.
I did this :-
NSString *stringToCompare = #"xyz";
[myArray enumerateObjectsUsingBlock:^(id *Obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString * tryString = [[myArray objectAtIndex:idx] description];
if ([tryString rangeOfString:stringToCompare].location == NSNotFound) {
// no match found
} else {
//match found and perform your operation. In my case i had removed array object at idx
}
}];