读一个.csv到NSObjects,然后按不同的标准对它们进行sorting

这是一个比与错误相关的问题更为开放的问题,所以如果你不喜欢回答这类问题,请不要着急。

我在.csv文件中有一个巨大的(!)船舶列表,

matrix是这样组织的: 在这里输入图像说明
用不同的数据重复约500次。

现在,我希望这被读入对象,可以进一步用来填充UITableView目前,我硬编码数据到目标文件,像这样

 arrayWithObjectsForTableView = [[NSMutableArray alloc] init]; if ([boatsFromOwner isEqualToString:@"Owner1"]) { cargoShips* ship = [[cargoShips alloc]init]; ship.name = @"name1"; ship.size = 1000; ship.owner = @"Owner1"; [self.boatsForOwner addObject:ship]; ship = [[cargoShips alloc]init]; ship.name = @"Name 2"; ship.size = 2000; ship.owner = @"Owner2"; 

等等,并与if-else的。 这是一个不好的方法,因为1)它枯燥,需要很长时间2)如果我想更新信息,需要更多的时间。 所以,我认为从matrix编程读取会更聪明,而不是自己做。 是的,队长明显来看我的大脑。

所以,这个问题! 我怎样才能读取如下所示的.csv文件: 在这里输入图像说明 将所有者的船只以对象的forms添加到NSMutableArray中。 (所以他们可以用来喂我的UITableView船舶。

我也想有select按照不同的东西sorting,如build设国家,运营商等。我怎样才能使相关的船只从.csv读取到相应的船舶的代码到对象? 我不知道编程多less,所以深入的答案将非常感激。

处理的深度将决定此任务需要哪种数据结构。 这是我会用的方法:

1:.csv文件读入一个巨大的NSString对象:

 NSString *file = [[NSString alloc] initWithContentsOfFile:yourCSVHere]; 

2:获取个人行:

 NSArray *allLines = [file componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; 

3:对于每一行,获取单个组件:

 for (NSString* line in allLines) { NSArray *elements = [line componentsSeparatedByString:@","]; // Elements now contains all the data from 1 csv line // Use data from line (see step 4) } 

4:这是由你决定的。 我首先想到的是创build一个类来存储所有的数据。 例如:

 @interface Record : NSObject //... @property (nonatomic, copy) NSString *name @property (nonatomic, copy) NSString *owner // ... etc @end 

4a:然后回到步骤3,为每一行创build一个Record对象,然后把所有的Record对象放入一个单独的NSArray (具有更大范围的东西!)。

5:使用包含所有Record对象的NSArray作为UITableView的数据源。

步骤4和步骤5的实施由您决定。 这可能是我如何做,但一个中型.csv文件。

编辑:这是如何生成Records

 // NSMutableArray *someArrayWithLargerScope = [[NSMutableArray alloc] init]; // NSString *file = [[NSString alloc] initWithContentsOfFile:yourCSVHere]; NSArray *allLines = [file componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]; for (NSString* line in allLines) { NSArray *elements = [line componentsSeparatedByString@","]; Record *rec = [[Record alloc] init]; rec.name = [elements objectAtIndex:0]; rec.owner = [elements objectAtIndex:1]; // And so on for each value in the line. // Note your indexes (0, 1, ...) will be determined by the // order of the values in the .csv file. // ... // You'll need one `Record` property for each value. // Store the result somewhere [someArrayWithLargerScope addObject:rec]; } 

在CSVparsing方面,假设你可以花费内存,把整个事情读入NSString可能是最容易的,在换行符上分割,然后用逗号分隔每一行,就像PLPiper所说的那样。

在那一点上,我会绕过键值编码。 在CSV文件中给出与您的运行时对象上的属性完全相同的名称。 那么你可以写一些像:

 // this method will create an object of the given type then push the values // from valueRow to the properties named by headingRow. So, ordinarily, // headingRow will be the first row in your CSV, valueRow will be any other - (id)populatedObjectOfType:(Class)type withHeadingRow:(NSArray *)headingRow valueRow:(NSArray *)valueRow { // we need the count of fields named in the heading row to // match the count of fields given in this value row if([headingRow count] != [valueRow count]) return nil; // autorelease if you're not using ARC id <NSObject> newInstance = [[type alloc] init]; // we need to enumerate two things simultaneously, so // we can fast enumerate one but not the other. We'll // use good old NSEnumerator for the other NSEnumerator *valueEnumerator = [valueRow objectEnumerator]; for(NSString *propertyName in headingRow) { [newInstance setValue:[valueEnumerator nextObject] forKey:propertyName]; } return newInstance; } ... elsewhere .... CargoShip *newShip = [self populateObjectOfType:[CargoShip class] withHeadingRow:[csvFile objectAtIndex:0] valueFor:[csvFile objectAtIndex:1]]; 

主要的警告是内置的机制将在标量和对象之间转换,而不是在不同types的对象之间转换。 所以,如果你有所有NSString和C整数types( shortintNSUInteger等),你会没事的,但是如果你有一些NSString s,比如说一些NSNumber那么你最终会得到存储在这个数字中的string插槽。 看起来你正在使用C的整数types(这是很正常的),所以你应该没问题。

在过滤方面,您可以使用NSPredicate 。 举个例子,假设你有一系列的CargoShip并且希望每个人的size至less为500:

 NSArray *bigShips = [allShips filteredArrayUsingPredicate: [NSPredicate predicateWithFormat:@"size > 500"]]; 

同样,对于sorting你可以抛出一些NSSortDescriptor的问题。 例如

 NSArray *shipsSortedBySize = [allShips sortedArrayUsingDescriptors: @[[NSSortDescriptor sortDescriptorWithKey:@"size" ascending:YES]]]; 

你可以使用这个链接,
https://github.com/davedelong/CHCSVParser
它是.csvparsing器,CHCSVParser可以configuration为parsing其他“字符分离”文件格式,如“TSV”(制表符分隔)或逗号分隔。