Search String into NSArray based on charcters order? - iphone

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
)

Related

How to sort an array with alphanumeric values?

I have an array which contains strings like frame_10#3x.png , frame_5#3x.png,frame_19#3x.png etc.
So I want to sort this array according to the number after the underscore i.e. the correct sequence will be frame_5#3x.png,frame_10#3x.png,frame_19#3x.png.
I tried to use the following method but no result:
NSInteger firstNumSort(id str1, id str2, void *context) {
int num1 = [str1 integerValue];
int num2 = [str2 integerValue];
if (num1 < num2)
return NSOrderedAscending;
else if (num1 > num2)
return NSOrderedDescending;
return NSOrderedSame;
}
Please suggest how to do this sorting for array.
NSArray *sry_img = [[NSArray alloc] initWithObjects:#"frame_18#3x.png",#"frame_17#3x.png",#"frame_1222#3x.png",#"frame_10#3x.png",#"frame_3#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",#"frame_1#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",nil];
NSArray *sortedStrings = [sry_img sortedArrayUsingSelector:#selector(localizedStandardCompare:)];
NSLog(#"%#",sortedStrings);
Enjy .......
But
localizedStandardCompare:, added in 10.6, should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact behavior of this method may be tweaked in future releases, and will be different under different localizations, so clients should not depend on the exact sorting order of the strings.
you want to do something like:
NSArray *components1 = [str1 componentsSeparatedByString:#"_"];
NSArray *components2 = [str2 componentsSeparatedByString:#"_"];
NSString *number1String = [components1 objectAtIndex:([components1 count] - 1])];
NSString *number2String = [components2 objectAtIndex:([components2 count] - 1])];
return [number1String compare:number2String];
I am not sure if my solution is the best possible approach but it can solve your problem for the time being :) .
1) First I have written a function to get the numbers before # character in your string and then I implemented simple SELECTION SORT algo to sort the array using this functions.
- (NSString*)getSubStringForString:(NSString*)value {
// First we will cut the frame_ string
NSMutableString *trimmedString = [NSMutableString stringWithString:[value substringWithRange:NSMakeRange(6, [value length]-6)]];
// New String to contain the numbers
NSMutableString *newString = [[NSMutableString alloc] init];
for (int i = 0; i < [trimmedString length] ; i++) {
NSString *singleChar = [trimmedString substringWithRange:NSMakeRange(i, 1)];
if (![singleChar isEqualToString:#"#"]) {
[newString appendString:singleChar];
} else {
break;
}
}
return newString;
}
This is the selection Implementation of the algo for sorting. The main logic is in the for loop. You can copy the code in viewDidLoad method to test.
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"frame_10#3x.png",#"frame_5#3x.png",
#"frame_3#3x.png", #"frame_19#3x.png",
nil];
NSLog(#"Values before Sort: %#", array);
int iPos;
int iMin;
for (iPos = 0; iPos < [array count]; iPos++)
{
iMin = iPos;
for (int i = iPos+1; i < [array count]; i++)
{
if ([[self getSubStringForString:[array objectAtIndex:i]] intValue] >
[[self getSubStringForString:[array objectAtIndex:iMin]] intValue]) {
iMin = i;
}
}
if ( iMin != iPos )
{
NSString *tempValue = [array objectAtIndex:iPos];
[array replaceObjectAtIndex:iPos withObject:[array objectAtIndex:iMin]];
[array replaceObjectAtIndex:iMin withObject:tempValue];
}
}
NSLog(#"Sorted Values: %#", array);
I hope that it can atleast keep you going. :)
You can try this-
NSString *str1 = [[[[str1 componentsSeparatedByString:#"frame_"] objectAtIndex:1] componentsSeparatedByString:#"#3x.png"] objectAtIndex:0];
int num1 = [str1 integerValue];

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
}
}];

How to compare array element?

Suppose I have an array having elements "am","john","rosa","freedom". I want to compare these elements and result would be the word and the size of the longest word. I am using objective C.
There isn't a "built-in" way of doing this, however you can use NSArray's sortedArrayUsingSelector: and create a category on NSString to provide a lengthCompare: method.
// NSString+LengthCompare.h
#import NSString.h
#interface NSString (LengthComparison)
- (NSComparisonResult)lengthCompare:(NSString *)aString;
#end
// NSString+LengthCompare.m
#import NSString+LengthCompare.h
#implememtation NSString (LengthComparison)
- (NSComparisonResult)lengthCompare:(NSString *)aString
{
if ([self length] < [aString length]) {
return NSOrderedAscending;
} else if ([self length] > [aString length]) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
#end
Now you can sort an of strings in ascending order using lengthCompare:
NSArray *array = [NSArray arrayWithObjects: #"am", #"john", #"rosa", #"freedom", nil];
NSArray *arraySortedByStringLength = [array sortedArrayUsingSelector:#selector(lengthCompare:)];
NString *shortestWord = [[arraySortedByStringLength objectAtIndex:0] retain];
NSLog(#"shortest word, %# has length %d", shortestWord, [shortestWord length];
[shortestWord release];
NString *longestWord = [[arraySortedByStringLength lastObject] retain];
NSLog(#"Longest word, %# has length %d", longestWord, [longestWord length];
[longestWord release];
Sounds like a classical logic exercise or is it something I miss in your question ?
int longestWordIndex = 0;
NSUInteger longestWordSize = 0;
for (int i=0 ; i<[nameArray count] ; i++) {
NSString* element = (NSString*)[nameArray objectAtindex:i];
if([element lenght] > longestWordSize) {
longestWordSize = [element lenght];
longestWordIndex = i;
}
}
NSLog("Longest word is %# with size of :%d", [nameArray objectAtIndex:longestWordIndex], longestWordSize);
I'll add one more approach to the two above -- use a block to do the body of your iteration.
__block NSUInteger longestWordSize = -1; // Make sure at least one object will be longer.
__block NSUInteger longestWordIndex;
[nameArray enumerateObjectsUsingBlock:^(id currentWord, NSUInteger index, BOOL *stop) {
if ([currentWord length] > longestWordSize) {
longestWordSize = [currentWord length];
longestWordIndex = index;
}
}];
NSLog("Longest word is %# with size of :%d", [nameArray objectAtIndex:longestWordIndex], longestWordSize);
Edit: The max and index have to be of storage type __block so they can be changed from inside the block.

Find indices of duplicates in a NSArray

i have an array like
[chapter,indent,left,indent,nonindent,chapter,chapter,indent,indent,left];
i need to find indexes of duplicates and also non duplicate elements .
how to do this...........give some sample code or logic......
thanks in advance
iam using objective c.....
NSArray *myWords = [string componentsSeparatedByString:#"class=\""];
int count_var=[myWords count];
tmp1=#"";
for(int i=1;i<count_var;i++)
{
str=[NSString stringWithFormat:#"\n%#",[myWords objectAtIndex:i]];
class=[str componentsSeparatedByString:#"\""];
NSString *tmp=[NSString stringWithFormat:#"%#",[class objectAtIndex:0]];
tmp1=[[NSString stringWithFormat:#"%#",tmp1] stringByAppendingString:[NSString stringWithFormat:#"%#",tmp]];
}
t1.editable=NO;
t1.text=tmp1;
NSArray *tempo=[[NSArray alloc]init];
tempo=[tmp1 componentsSeparatedByString:#"\n"];
tempCount=[tempo count];
this is my sample code...in this the array tempo contains all objects from that array i want to get index of duplicate stringsā‰„.
You could build a dictionary mapping the objects to index sets. For every index set, a -count of 1 means no duplicates, > 1 means there are duplicates.
NSArray *arr = [NSArray arrayWithObjects:...];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSUInteger i=0; i<[arr count]; ++i) {
id obj = [arr objectAtIndex:i];
NSMutableIndexSet *ids = [dict objectForKey:obj];
if (!ids) {
ids = [NSMutableIndexSet indexSet];
[dict setObject:ids forKey:obj];
}
[ids addIndex:i];
}
NSLog(#"%#", dict);