Objective C read csv file and use array - objective-c

I have a csv file as this:
1#one#two#three#four;
2#apple#tower#flower#robot;
I read this file with this code:
NSString *resourceFileName = #"PrenotazioniDb";
NSString *pathToFile =[[NSBundle mainBundle] pathForResource: resourceFileName ofType: #"txt"];
NSError *error;
NSString *fileString = [NSString stringWithContentsOfFile:pathToFile encoding:NSUTF8StringEncoding error:&error];
if (!fileString) {
NSLog(#"Error reading file.");
}
NSScanner *scanner = [NSScanner scannerWithString:fileString];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"\n#; "]];
NSString *one = nil, *two = nil, *three = nil, *four = nil;
while ([scanner scanUpToString:#"#" intoString:&one] && [scanner scanUpToString:#"#" intoString:&two] && [scanner scanUpToString:#"#" intoString:&three] && [scanner scanUpToString:#"#" intoString:&four]{
}
but I want memorize the file in an array, What can I do? I should use two array: one for line and one for single word; for example in first array in a position I store
1#one#two#three#four;
and in the second array I store in first position "1" in second "one" in third "two" ext....
What Can i Do?

You can use the componentsSeparatedByString method.
NSString *list=#"1#one#two#three#four";
NSArray *listItems = [list componentsSeparatedByString:#"#"];
NSLog(#"listItems= %#",listItems);
prints:
listItems= (
1,
one,
two,
three,
four
)

Related

Obj-C: Create Array From String Where items are in <>

I am trying to parse a String to an Array each item is between <> for example <this is column 1><this is column 2> etc....
Help would be much appreciated.
Thanks
Something to demonstrate:
NSString *string = #"<this is column 1><this is column 2>";
NSScanner *scanner = [NSScanner scannerWithString:string];
NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
NSString *temp;
while ([scanner isAtEnd] == NO)
{
// Disregard the result of the scanner because it returns NO if the
// "up to" string is the first one it encounters.
// You should still have this in case there are other characters
// between the right and left angle brackets.
(void) [scanner scanUpToString:#"<" intoString:NULL];
// Scan the left angle bracket to move the scanner location past it.
(void) [scanner scanString:#"<" intoString:NULL];
// Attempt to get the string.
BOOL success = [scanner scanUpToString:#">" intoString:&temp];
// Scan the right angle bracket to move the scanner location past it.
(void) [scanner scanString:#">" intoString:NULL];
if (success == YES)
{
[array addObject:temp];
}
}
NSLog(#"%#", array);
NSString *input =#"<one><two><three>";
NSString *strippedInput = [input stringByReplacingOccurencesOfString: #">" withString: #""]; //strips all > from input string
NSArray *array = [strippedInput componentsSeperatedByString:#"<"];
Note that [array objectAtIndex:0] will be an empty string ("") an this doesn't work of course, if one of the "actual" string contain < or >
One approach might be to use either componentsSeparatedByCharactersInSet or componentsSeparatedByString from NSString.
NSString *test = #"<one> <two> <three>";
NSArray *array1 = [test componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
NSArray *array2 = [test componentsSeparatedByString:#"<"];
You'll need to do some cleaning up afterward, either trimming in the case of array2 or removing white-space strings in the case of array1

Objective C: Get Substring between Double Quotes

What would be the best way to get every substring between double quotes and make it into an array?
For example, if the string (NSString) is:
#"abcd \"efgh\" ijklm \"no\" p \"qrst\" uvwx \"y\" z"
I want the result to be:
{#"efgh", #"no", #"qrst", #"y"}
as an NSArray.
This should get you started:
NSString *str = #"abcd \"efgh\" ijklm \"no\" p \"qrst\" uvwx \"y\" z";
NSMutableArray *target = [NSMutableArray array];
NSScanner *scanner = [NSScanner scannerWithString:str];
NSString *tmp;
while ([scanner isAtEnd] == NO)
{
[scanner scanUpToString:#"\"" intoString:NULL];
[scanner scanString:#"\"" intoString:NULL];
[scanner scanUpToString:#"\"" intoString:&tmp];
if ([scanner isAtEnd] == NO)
[target addObject:tmp];
[scanner scanString:#"\"" intoString:NULL];
}
for (NSString *item in target)
{
NSLog(#"%#", item);
}
One way would be to use componentsSeparatedByString: to split them based on ". This should give you an array of words the count of which should be odd. Filter all the even numbered words into an array. This should be your desired array.
Alternatively look at NSPredicate.

make array out of string with variable number of spaces in Objective-C

This is the code that I would use if it was always single spaces in between words. Since I have multiple spaces in between some words how can my code be changed to remove the extra spaces when using componentsSeparatedBySring. I'm new to OBjective-C so any help would be greatly appreciated!
Here is my code:
NSString *myString = #"One Two Three Four Five";
NSArray *myArray = [myString componentsSeparatedByString: #" "];
Use NSScanner instead:
NSMutableArray *results = [NSMutableArray array];
NSScanner *scanner = [NSScanner scannerWithString:input];
NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:#" "];
while ([scanner isAtEnd] == NO)
{
NSString *string;
[scanner scanUpToCharactersFromSet:charSet intoString:&string];
[results addObject:string];
}
+ (NSArray *)componentsInString:(NSString *)string withSeparacterInString:(NSString *)separaterStr
{
if (!string || !separaterStr || [separaterStr length] < 1)
return [NSArray array];
NSMutableArray *arr = [[string componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:separaterStr]] mutableCopy];
[arr removeObject:#""]; // removes all empty components
return arr;
}
NSArray *arr = [Utils componentsInString:#"12 123 \n 14 " withSeparacterInString:#" \n"];

How would you parse the location text from Twitter to get the latitude/longitude in Objective-C?

The location text from Twitter could be just about anything. Sometimes Twitter clients set the location with the user's latitude and longitude in the following format.
"\U00dcT: 43.05948,-87.908409"
Since there is no built-in support for Regular Expressions in Objective-C I am considering using the NSString functions like rangeOfString to pull the float values out of this string.
For my current purpose I know the values with start with 43 and 87 so I can key off those values this time but I would prefer to do better than that.
What would you do to parse the latitude/longitude from this string?
This way won't create nearly as many intermediate objects:
float latitude, longitude;
NSString *exampleString = #"\U00dcT: 43.05948,-87.908409";
NSScanner *scanner = [NSScanner scannerWithString:exampleString];
NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
[scanner scanUpToCharactersFromSet:digits intoString:null];
[scanner scanFloat:&lattitude];
[scanner scanUpToCharactersFromSet:digits intoString:null];
[scanner scanFloat:&longitude];
This appears to work well but I am still interested in what other approaches could work better.
- (CLLocation *)parseLocationText:(NSString *)lt {
// location = "\U00dcT: 43.05948,-87.908409";
NSString *strippedString = [lt stringByTrimmingCharactersInSet:[NSCharacterSet letterCharacterSet]];
NSLog(#"strippedString: %#", strippedString);
if ([strippedString rangeOfString:#","].location != NSNotFound) {
NSArray *chunks = [strippedString componentsSeparatedByString: #","];
if (chunks.count == 2) {
NSLog(#"lat: %#", [chunks objectAtIndex:0]);
NSLog(#"long: %#", [chunks objectAtIndex:1]);
NSString *latitude = [chunks objectAtIndex:0];
NSString *longitude = [chunks objectAtIndex:1];
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[loc autorelease];
return loc;
}
}
return nil;
}

How to use NSScanner?

I've just read Apple documentation for NSScanner.
I'm trying to get the integer of this string:
#"user logged (3 attempts)"
I can't find any example, how to scan within parentheses. Any ideas?
Here's the code:
NSString *logString = #"user logged (3 attempts)";
NSScanner *aScanner = [NSScanner scannerWithString:logString];
[aScanner scanInteger:anInteger];
NSLog(#"Attempts: %i", anInteger);
Ziltoid's solution works, but it's more code than you need.
I wouldn't bother instantiating an NSScanner for the given situation. NSCharacterSet and NSString give you all you need:
NSString *logString = #"user logged (3 attempts)";
NSString *digits = [logString stringByTrimmingCharactersInSet:
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
NSLog(#"Attempts: %i", [digits intValue]);
or in Swift:
let logString = "user logged (3 attempts)"
let nonDigits = NSCharacterSet.decimalDigitCharacterSet().invertedSet
let digits : NSString = logString.stringByTrimmingCharactersInSet(nonDigits)
NSLog("Attempts: %i", digits.intValue)
`Here is what I do to get certain values out of a string
First I have this method defined
- (NSString *)getDataBetweenFromString:(NSString *)data leftString:(NSString *)leftData rightString:(NSString *)rightData leftOffset:(NSInteger)leftPos;
{
NSInteger left, right;
NSString *foundData;
NSScanner *scanner=[NSScanner scannerWithString:data];
[scanner scanUpToString:leftData intoString: nil];
left = [scanner scanLocation];
[scanner setScanLocation:left + leftPos];
[scanner scanUpToString:rightData intoString: nil];
right = [scanner scanLocation] + 1;
left += leftPos;
foundData = [data substringWithRange: NSMakeRange(left, (right - left) - 1)]; return foundData;
}
Then call it.
foundData = [self getDataBetweenFromString:data leftString:#"user logged (" rightString:#"attempts)" leftOffset:13];
leftOffset is the number of characters for the left string
Could be an easier cleaner way but that was my solution.
Here is a simple solution using NSScanner (yes, #NSResponder has a really neat solution!):
NSString *logString = #"user logged (3 attempts)";
NSString *numberString;
NSScanner *scanner = [NSScanner scannerWithString:logString];
[scanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:nil];
[scanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:&numberString];
NSLog(#"Attempts: %i", [numberString intValue]);
NSLog output:
Attempts: 3
NSScanner is a linear scanner. You have to scan through the stuff you don't want to get to what you do want.
You could do [aScanner scanUpToCharactersInSet:[NSCharacterSet decimalDigitCharacterSet] intoString:NULL] to jump past everything up to the number character. Then you do [aScanner scanInteger:&anInteger] to scan the character into an integer.
here is the reg-ex usage
NSString *logString = #"user logged (3 attempts)";
NSString * digits = [logString stringByMatching:#"([+\\-]?[0-9]+)" capture:1];