9

これはエラー関連の質問というよりも未解決の質問なので、この種の質問に答えたくない場合は、炎上しないでください。

.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の場合も同様です。これは悪い方法です。1)退屈で時間がかかる2)情報を更新したい場合はさらに時間がかかります。したがって、自分で行うよりも、マトリックスからプログラムで読み取る方が賢明だと思いました。ええ、キャプテンは明らかに私の脳を訪問するために来ました。

だから、質問に! 次のような.csvファイルを読み取るにはどうすればよいですか ここに画像の説明を入力してください 。たとえば、所有者の船をNSMutableArrayオブジェクトの形でに追加します。UITableView(それで、彼らは私の船を養うために使うことができます。

また、ビルドの国、オペレーターなど、さまざまなもので並べ替えるオプションも必要です。.csvから読み取った関連する船をオブジェクトにフィードするコードを作成するにはどうすればよいですか?私はプログラミングをあまり知らないので、詳細な回答をいただければ幸いです。

4

3 に答える 3

11

処理の深さによって、このタスクに必要なデータ構造の種類が決まります。これは私が使用する方法です:

1:.csvファイルを 1 つの巨大な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];
}
于 2013-01-25T01:48:18.280 に答える
3

このリンクを使用でき
ます
。カンマ区切り。

于 2013-01-25T06:28:53.420 に答える
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 整数型 ( shortintNSUIntegerなど) があれば問題ありませんが、いくつかNSStringの s と、たとえばいくつかの s がある場合NSNumber、数値スロットに格納された文字列になってしまいます。C の整数型を使用しているように見えるので (ごく普通のことですが)、問題ないはずです。

フィルタリングに関しては、NSPredicates を使用できます。たとえば、s の配列があり、少なくとも 500CargoShipの a を持つすべての配列が必要だとします。size

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

同様に、ソートの場合、問題にいくつかの s を投げることができますNSSortDescriptor。例えば

NSArray *shipsSortedBySize = [allShips sortedArrayUsingDescriptors:
     @[[NSSortDescriptor sortDescriptorWithKey:@"size" ascending:YES]]];
于 2013-01-25T02:18:45.027 に答える