-3

I've created an iPhone app that has a dictionary array of locations (lat,long,point). I created the array by manually entering each value.

myLocationArray = @[
                 @{
                   kStation : @"1",
                   kLatitude : @( 41.656467),
                   kLongitude : @(-81.277963)
                   },
                 @{
                   kStation : @"2",
                   kLatitude : @(41.657118),
                   kLongitude : @(-81.276545)
                   },
                 @{
                   kStation : @"3",
                   kLatitude : @(41.658493),
                   kLongitude : @(-81.273542)
                   },
                  ...

This is good and works but now I want to create this array programmatically by getting the data from a .CSV file. I have a .CSV file (TestCSV.csv) that looks like this.

41.656467,-81.277963,27200
41.657118,-81.276545,27650
41.658493,-81.273542,28631.5
41.660728,-81.268547,30195
41.661830,-81.266065,30991
41.662828,-81.263819,31700
41.663677,-81.261962,32300
41.664578,-81.259909,32950
41.666210,-81.256312,34100
41.666921,-81.254708,34605
41.668043,-81.252191,35400
41.669044,-81.250043,36099
41.670120,-81.247495,36900
41.670778,-81.245957,37380
41.671459,-81.244292,37905
41.672028,-81.242832,38349
41.672487,-81.241702,38700
41.673106,-81.240175,39175
41.674364,-81.237007,40150
41.675170,-81.235038,40762.5
41.675716,-81.233698,41182
41.676143,-81.232614,41516

Specifically, I'd like to create myLocationArray (with formatting as shown) by reading straight from the TestCSV.csv. I'm not familiar with the code to achieve this and would really appreciate some direction.

Also, would it be any different or easier if the data was provided via text file instead of csv?

3
  • Have you done any searching on parsing CSV files? There are plenty of existing question here or found on Google that will help you parse a CSV file with Objective-C. Commented May 11, 2013 at 16:21
  • possible duplicate of Using NScanner to parse CSV File to Dictionary Array Commented May 12, 2013 at 15:02
  • 1
    Direct duplicate of your own question - please do not do that Commented May 12, 2013 at 15:03

3 Answers 3

5

Try

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Locations" ofType:@"csv"];
NSString *csvString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];

NSArray *locations = [csvString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

NSMutableArray *locationsArray = [NSMutableArray array];
for (NSString * location in locations)
{

    NSArray *components = [location componentsSeparatedByString:@","];

    double latitude   = [components[0] doubleValue];
    double longitude  = [components[1] doubleValue];
    NSString *station =  components[2];

    NSDictionary *dict = @{@"kLatitude": @(latitude),
                           @"kLongitude": @(longitude),
                           @"kStation": station};

    [locationsArray addObject:dict];

}

CSV File

Answer inspired from

Sign up to request clarification or add additional context in comments.

4 Comments

I was not able to create an array from this. In filepath should pathForResource: be @"TestCSV" since that is the name of my csv file that contains my data? Aside from that, I get the error *** Terminating app due to uncaught exception 'NSRangeException', reason: '** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
Using the debugger and breaks, I think the problem lies in this call, [components enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [dict setObject:obj forKey:keys[idx]]; }];. I'm not sure how this works but perhaps you can make sense of why it's causing the error I posted in the previous comment.
@JBeesky Did you use the exact code that I provided? Everything is working fine for me. First check with the CSV that I used. Check what is different in both. In enumeration I have used the idx to find the key, if the idx comes more than 2, it would break. It would more easier if you provide the CSV you used.
I updated my question to show the actual csv file data I'm using in my project. I don't think there would be an index 3 though.
1

csv file IS a plain-text file. To achive what you want you can use NSScanner and NSString componentsSeparatedByString: Everything else is really simple.

6 Comments

Using componentsSeparatedByString: to parse a CSV file only works in very specific cases. It won't work if values are quoted and values contain field delimiters. It won't work when values contain newlines. Admittedly, it may work in this specific case since this CSV file appears not to have any text but it is not a valid, general purpose solution for parsing CSV files.
No one asked for general purpose solution. Topic starter gave file example he want to parse. It can be parsed with method I mentioned. I'm not a fan of general purpose solutions when they are clearly unnecessary.
I was simply pointing out the potential downsides to your answer for the benefit of people who may find your answer in the future. Remember, people will search and find such answers long into future and such users may have a more general need. I stated in my comment that your answer is fine for this use.
Thanks for the response guys. I'm looking into NSSCanner. I'll report back after I do some research.
Guys, I posted a new question at the following link in response to your suggestion to use NSScanner. I'd like keep this question open as well for the possibility that Anupdas's method may work. Please review and comment to stackoverflow.com/questions/16503084/…. I appreciate the help.
|
1

Answer provided by Anupdas. Cheers!

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Locations" ofType:@"csv"];
NSString *csvString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];

NSArray *locations = [csvString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

NSMutableArray *locationsArray = [NSMutableArray array];
for (NSString * location in locations)
{

NSArray *components = [location componentsSeparatedByString:@","];

double latitude   = [components[0] doubleValue];
double longitude  = [components[1] doubleValue];
NSString *station =  components[2];

NSDictionary *dict = @{@"kLatitude": @(latitude),
                       @"kLongitude": @(longitude),
                       @"kStation": station};

[locationsArray addObject:dict];

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.