这是一个比错误相关的问题更开放的问题,所以如果你不想回答这些问题,请不要火焰。
我在.csv文件中有一个巨大的(!)船只列表,以,
矩阵的组织方式如下:
用不同的数据重复约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's。这是一个糟糕的方法,如 1)它很无聊,需要很长时间 2)如果我想更新信息,则需要更多时间。 所以,我认为从矩阵中以编程方式读取而不是自己做它会更聪明。是的,船长显然是为了访问我的大脑。
所以,问题!
如何读取如下所示的.csv文件:
以对象的形状将所有者的船只添加到NSMutableArray
。 (所以他们可以用来喂我的UITableView
船。
我还想选择按照不同的东西排序,例如构建国家,运营商等。如何将从.csv读取的相关船只的代码转换为对象? 我不太了解编程,因此非常感谢深入的答案。
答案 0 :(得分:11)
处理的深度将决定此任务所需的数据结构类型。这是我将使用的方法:
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:这取决于您。我的第一个想法是创建一个类来存储你的所有数据。例如:
@interface Record : NSObject
//...
@property (nonatomic, copy) NSString *name
@property (nonatomic, copy) NSString *owner
// ... etc
@end
4a:然后,在步骤3中为每一行创建一个Record
对象,然后将所有Record对象放入一个单独的NSArray
(范围更大的东西! )。
5:使用包含所有NSArray
个对象的Record
作为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];
}
答案 1 :(得分:3)
就CSV解析而言,假设你可以花费内存,它可能最容易在整个事物中读到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]];
主要警告是内置机制将在标量和对象之间进行转换,但不会在不同类型的对象之间进行转换。因此,如果您拥有所有NSString
和C整数类型(short
,int
,NSUInteger
等),那么您可以,但如果您有一些{{ 1}} s,比如一些NSString
s,那么你最终会得到存储在数字槽中的字符串。看起来你正在使用C整数类型(这很正常)所以你应该没问题。
在过滤方面,您可以使用NSNumber
s。例如,假设您有一个NSPredicate
的数组,并希望每个CargoShip
至少为500:
size
同样,对于排序,您可以在问题上抛出一些NSArray *bigShips = [allShips filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:@"size > 500"]];
。 E.g。
NSSortDescriptor
答案 2 :(得分:3)
你可以使用这个链接,
https://github.com/davedelong/CHCSVParser
它是.csv解析器,CHCSVParser可以配置为解析其他“字符分隔”文件格式,例如“TSV”(tab-seperated)或逗号分隔。