一連の場所を含むCSVファイルを使用するゲームを作成しています。
これは、CSVファイルの1つの短い抜粋です。
Name,Region,Country,Type
Bath,Somerset,United Kingdom,City
Brighton and Hove,Sussex,United Kingdom,City
Canterbury,Kent,United Kingdom,City
Chichester,West Sussex,United Kingdom,City
Durham,Durham,United Kingdom,City
Clevedon,Somerset,United Kingdom,Town
このデータを読み取り、フィールド(Name、Region、Country、Type)を含む配列と、データのすべての行(フィールドの下にあるもの)を含む別の多次元配列を作成するクラスを作成しました。
MySqlには、特定のフィールドの行をグループ化して、クラスに実装したすべての重複を削除する関数があります。私の問題はそこにあります。
この関数を使用してRegionフィールドをグループ化しました。このフィールドを上記のCSVデータで使用すると、Somerset、Sussex、West Sussex、Durham、Kentを含む配列が返されます。(上記の2つではなく1つのサマセットしかないことに注意してください)。ただし、末尾にスペースがあるリージョン、つまり「Somerset」が返されます。
CSVファイルをチェックし、見つけたすべてのスペースを削除して、スペルミスのある領域がないことを確認しましたが、これで修正されませんでした。また、クラスグループの前にコンソールにすべてのリージョンを出力すると、すべてのリージョンが正常に表示されます。
ただし、リージョンをNSSetに入れると、問題が発生することがわかりました。CSVデータの後ろにスペースがないリージョンは、突然、末尾にスペースが付いた重複バージョンになります。(つまり、NSSetにはサマセットと「サマセット」がありますが、サマセットのみが必要です)。
CSVには何の問題もありません。すべてのデータを正しく取得したので、ファイル読み取りルーチンはCSVを正常に解析しました。それをNSSetに入れて初めて、重複を完全に削除する必要があるため、奇妙な問題が発生します。
これがCSVクラスの私のコードです
ヘッダ:
//
// CSV.h
// Guess The Distance
//
// Created by James Campbell on 15/02/2012.
// Copyright (c) 2012 Cirencester College. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface CSV : NSObject {
NSMutableArray *fields;
NSMutableArray *rows;
}
@property (strong, readonly) NSMutableArray *fields;
@property (strong, readonly) NSMutableArray *rows;
-(CSV *)initWithCSVNamed:(NSString *)name fieldSeperator:(NSString *)fieldSeperator rowSeperator:(NSString *)rowSeperator;
-(NSDictionary *)getRowAtIndex:(NSUInteger)index;
-(NSArray *)getRowsForField:(NSString *)field Group:(BOOL)group;
@end
実装:
//
// CSV.m
// Guess The Distance
//
// Created by James Campbell on 15/02/2012.
// Copyright (c) 2012 Cirencester College. All rights reserved.
//
#import "CSV.h"
@implementation CSV
@synthesize fields, rows;
-(CSV *)initWithCSVNamed:(NSString *)name fieldSeperator:(NSString *)fieldSeperator
rowSeperator:(NSString *)rowSeperator{
self = [super init];
NSLog(@"Reading CSV File...");
NSString *filePath;
if ([[name pathExtension] isEqualToString:@""]){
filePath = [[NSBundle mainBundle] pathForResource:name ofType:nil];
} else {
filePath = [[NSBundle mainBundle] pathForResource:[[name lastPathComponent] stringByDeletingPathExtension] ofType:[name pathExtension]];
}
NSData *csvData = [NSData dataWithContentsOfFile:filePath];
if (csvData) {
NSString *csvString = [[NSString alloc] initWithData:csvData encoding:NSASCIIStringEncoding];
NSArray *csvRows = [csvString componentsSeparatedByString:rowSeperator];
rows = [[NSMutableArray alloc] initWithCapacity:[csvRows count]-1];
__block NSIndexSet *fieldIndexes;
[csvRows enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSArray *csvFields = [(NSString *)obj componentsSeparatedByString:fieldSeperator];
if(idx == 0){
fieldIndexes = [csvFields indexesOfObjectsPassingTest:
^BOOL (id el, NSUInteger i, BOOL *stop) {
return (![(NSString *)el isEqualToString:@""]);
}];
fields = [[NSMutableArray alloc] initWithArray:[csvFields objectsAtIndexes:fieldIndexes]];;
} else {
[rows insertObject:[csvFields objectsAtIndexes:fieldIndexes] atIndex:idx-1];
}
}];
}
return self;
}
-(NSDictionary *)getRowAtIndex:(NSUInteger)index{
NSArray *row = [rows objectAtIndex:index];
return [[NSDictionary alloc] initWithObjects:row forKeys:fields];
}
-(NSArray *)getRowsForField:(NSString *)field Group:(BOOL)group{
NSUInteger fieldIndex = [fields indexOfObject:field];
id items;
if (!group){
NSMutableArray *itemArray = [[NSMutableArray alloc] init];
items = itemArray;
} else {
NSMutableSet *itemSet = [[NSMutableSet alloc] init];
items = itemSet;
}
[rows enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *row = [(NSArray *)obj objectAtIndex:fieldIndex];
NSLog(@"|%@|", row);
[items addObject:row];
}];
NSLog(@"%@", [items description]);
if (!group){
return [items copy];
} else {
return [items allObjects];
}
}
@end