views:

3352

answers:

3

I have a web service which returns tab delimited data (see sample below).

I need to parse this into an array or similar so I can create a navigation view of it.

I've managed to perform the web request and could parse an XML file, but my knowledge of Objective-C is small.

433 Eat
    502 Not Fussed
    442 British
    443 Chinese
    444 Dim Sum
    445 Fish
    446 French
    447 Gastropubs
    449 Indian
    451 Italian
    452 Japanese
    453 Middle Eastern
    454 Pan-Asian
    455 Pizza
    456 Spanish
    457 Tapas
    458 Thai
    459 Vegetarian
434 Drink
    501 Not Fussed
    460 Bars 
    461 Pubs
+3  A: 

I'm not sure I understand your format exactly (it displays a little strange to me) but the easiest way to do this is with - (NSArray *)componentsSeparatedByString:(NSString *)separator which is a method in the NSString class... example:

NSArray *components = [myString componentsSeperatedByString:@"\t"];

This returns an NSArray of NSStrings, one for each tab-delimited field. If the new-line separators are important you can use - (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator (also on NSString) to split using more than one kind of delimiter.

Brett
Those won't work—they'll return a single flat list. Looking at his example, it looks like indentation is important.
Peter Hosey
Thanks Brett I had actually found this class myself earlier, still struggling but its a point in the right direct...next question being added....
tigermain
Peter - it is kinda working, however I am loosing the 1st record of the fields which begins with a tab, any suggestions?
tigermain
If the first field begins with a tab, remove it with the NSString method:- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)setwhich can help you trim tabs from the beginning and ending of the NSString.
Brett
tigermain: See my answer.
Peter Hosey
Peter's answer is more correct if the indentation level is important. I thought that was a formatting error!
Brett
+1  A: 

I had a feeling more than a flat list is wanted. If you want a multidimensional structure you can do something like this:

NSArray *lines = [data componentsSeparatedByString:@"\n"];
for (NSString *line in lines) {
    NSArray *fields = [line componentsSeparatedByString:@"\t"];
     // Do something here with each two-element array, such as add to an NSDictionary or to an NSArray (to make a multidimensional array.)
}
Brett
That's exactly what I had coded with an additional tweak to handle my slightly dodgy column structure
tigermain
+2  A: 

You're on the right track with NSScanner. You'll need at least two scanners: One to scan lines from the whole input string, and one scanner for each line. Set the whole-input scanner to skip only whitespace (not newlines), then:

  1. Scan one line (source string up to end-of-line).
  2. Create a scanner and have it scan tabs from the line.
  3. Count the tabs you scanned. That's your indentation level.
  4. The rest of the line is the entry number and name. You could scan the line up to whitespace to separate the number and name, or leave them together, depending on what you need.
  5. Go back to step 1.

For specific method names, see the NSScanner class reference and the NSCharacterSet class reference.

Peter Hosey