How to search in NSArray? - iphone

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.

Related

Reading from NSMutableArray throws exception at item 2 even though it exists

I've got a file with a bunch of string in like so:
item1,01-SR,admin,Missing or broken,undefined, 16/04/2013 18:10:10;
item1,03-SR,admin,In Use,undefined, 16/04/2013 18:10:34;
item1,01-SR,admin,In Use,undefined, 16/04/2013 18:10:45;
item1,02-SR,admin,In Use,undefined, 16/04/2013 18:10:49;
item1,05,admin,In Use,undefined, 16/04/2013 18:10:56;
I'm reading the strings in and then splitting them up so I just get one string at a time. Then I want to split up the string I've got again so each CSV is it's own variable. I've tried this like so (numLines is a count of the number of lines in the file):
while (count1 < numLines) {
NSString *message = [[strings objectAtIndex: count1] copy];
NSMutableArray *items = [[fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#";"]] mutableCopy];
NSString *items1 = [[items objectAtIndex: count1] copy];
NSLog(#"items: %#", items1);
NSMutableArray *inditems = [[items1 componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]] mutableCopy];
NSString * item1 = inditems[0];
NSString * bnum1 = inditems[1];
NSString * user1 = inditems[2];
NSString * state1 = inditems[3];
NSString * gender1 = inditems[4];
NSString * tstamp1 = inditems[5];
NSLog(#"item: %#", item1);
NSLog(#"bnum: %#", bnum1);
NSLog(#"user: %#", user1);
NSLog(#"state: %#", state1);
NSLog(#"gender: %#", gender1);
NSLog(#"tstamp: %#", tstamp1);
count1++;
}
Now, this works as far as selecting one line from the file and it puts the first two items into the array and then writes the values of item1 and bnum1 to the log but then it throws an exception for some reason. Now this would usually suggest to me that item 2 doesn't exist in the array so I did a count like so:
NSLog(#"count = %d", [inditems count]);
Which correctly returns 6. I then wanted to check that it could actually read another item from the array so I did:
NSString *tstamp1 = [[inditems lastObject] copy];
Which when logged correctly returns the time stamps like so:
16/04/2013 18:10:10
So I thought "oh at least item 5 works" and tried just getting that item:
while (count1 < numLines) {
NSString *message = [[strings objectAtIndex: count1] copy];
NSMutableArray *items = [[fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#";"]] mutableCopy];
NSString *items1 = [[items objectAtIndex: count1] copy];
NSLog(#"items: %#", items1);
NSMutableArray *inditems = [[items1 componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]] mutableCopy];
NSString * item1 = inditems[0];
NSString * bnum1 = inditems[1];
NSString * tstamp1 = inditems[5];
NSLog(#"item: %#", item1);
NSLog(#"bnum: %#", bnum1);
NSLog(#"tstamp: %#", tstamp1);
count1++;
}
But that also throws an exception! I'm probably doing something stupid here, but I would appreciate any help.
Thanks!
My guess is your NSArray *strings is including empty value which is causing your error. You need to check it first and then do your logic.
//path is your file path
NSString* fileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSArray *strings = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
for (int i = 0; i < [strings count]; i++){
if (![[strings objectAtIndex:i] isEqualToString:#""]){
//Here do your code...
}
}

Compare two strings and remove common elements

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.

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
)

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 remove quote and slash from string in iphone

Hi friends... I am using regular expression so I get string but with double quote and slash but I dont want that. I want string value without slash and double quotes. I try this I'm but not getting proper answer.
I get error after running application [/Users/pradeepyadav/Desktop/RegexKitLiteDemo/Classes/RegexKitLiteDemoAppDelegate.m:108:0 /Users/pradeepyadav/Desktop/RegexKitLiteDemo/Classes/RegexKitLiteDemoAppDelegate.m:108: error: incompatible block pointer types initializing 'void (^)(struct NSString *, NSUInteger, BOOL *)', expected 'void (^)(struct objc_object *, NSUInteger, BOOL *)
I get this error line
Second one is this : [/Users/pradeepyadav/Desktop/RegexKitLiteDemo/Classes/RegexKitLiteDemoAppDelegate.m:105:0 /Users/pradeepyadav/Desktop/RegexKitLiteDemo/Classes/RegexKitLiteDemoAppDelegate.m:105: warning: 'NSString' may not respond to '+stringByTrimmingCharactersInSet:
I get this error line [webData length] encoding:NSUTF8StringEncoding];
//NSLog(#"%#",loginStatus);
[connection release];
//
NSString *regexString = #"Stations\\[""(.*)""\\] = new Station\\((.*)new Array\\((.*)\\)\\);"; //#"Stations\\[""(.*)""\\] = new Station\\((.*)\\);"; //#"Stations\[""(.*)""\] = new Station\({[\,,2}(.*)new Array\((.*)\)\);"; //#"<a href=([^>]*)>([^>]*) - ";
matchArray = [loginStatus arrayOfCaptureComponentsMatchedByRegex:regexString];
NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:[matchArray count]];
//NSCharacterSet *charactersToRemove = [NSCharacterSet punctuationCharacterSet];
[matchArray enumerateObjectsUsingBlock:^(NSString *aString, NSUInteger idx, BOOL *stop)
{
NSString *newString = [NSString stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];//#############
[newArray insertObject:newString atIndex:idx];
NSLog(#"matchArray: %#", matchArray);
}];//******************
//NSLog(#"matchArray: %#", matchArray);
lstAirports = [[NSMutableArray alloc] initWithCapacity:[matchArray count]];
for (int i = 0; i < [matchArray count]; i++) {
airport *air=[[airport alloc]init];
//code
air.Code = [[matchArray objectAtIndex: i] objectAtIndex: 1];
NSLog(#"air.Code: %#\n",air.Code);
//name
NSString *temp=[[matchArray objectAtIndex: i] objectAtIndex: 2];
NSArray *arrParts=[temp componentsSeparatedByString:#""","];
//air.Name=arrParts[2];
air.Name=[arrParts objectAtIndex:2];
NSLog(#"air.Name: %#\n",air.Name);
//destination airports
temp=[[matchArray objectAtIndex: i] objectAtIndex: 3];
arrParts=[temp componentsSeparatedByString:#","];
air.DestinationAirports =arrParts;
NSLog(#"air.DestinationAirports: %#\n",air.DestinationAirports);
[lstAirports addObject: air];
NSLog(#"lstAirports: %#\n",lstAirports);
}
//[webData release];
}
please some help me fast it's vital for me
You don't need RegExp to remove occurrences of string in NSString.
See the example below, i hop it will help you:
NSString *str = #"fdf\"fdsfdsf\"fsdfsf/fsdfsdfsf\\fsdfsdf\\fsdffsd//fsdfsf\"fsdf/\\\"";
str = [str stringByReplacingOccurrencesOfString:#"\"" withString:#""];
str = [str stringByReplacingOccurrencesOfString:#"\\" withString:#""];
str = [str stringByReplacingOccurrencesOfString:#"/" withString:#""];
NSLog(#"%#", str);
Check for the usage of
stringByReplacingOccurrencesOfString:withString:
in
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html.
You can replace them with "" characters.