将.csv数据导入数组

时间:2014-07-28 14:38:33

标签: arrays macos csv import swift

我过去几年使用过Objective-C。 现在我用swift尝试Xcode 6 beta 4。

我想将.csv格式导入我的网络服务器。我在Objective-C中的旧代码是:

NSString *stringURL = @"https:// [URL] /versionen/versionen.csv";
NSURL  *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
    NSString *csvResponseString = [[NSString alloc] initWithData:urlData   encoding:NSUTF8StringEncoding];
    NSArray         *MZVersionDatenZeilen = [csvResponseString componentsSeparatedByString:@"\n"];
    NSEnumerator    *MZVersionEnumerator = [MZVersionDatenZeilen objectEnumerator];
    NSMutableArray  *MZVersionDatenArray = [NSMutableArray arrayWithCapacity:[MZVersionDatenZeilen count]];
    NSString        *MZVersionZeile;
    while (MZVersionZeile = [MZVersionEnumerator nextObject])
    {
        [MZVersionDatenArray addObject:[MZVersionZeile componentsSeparatedByString:@";"]];
    }
}

我怎么能在Swift中这样做? 有最佳做法 - 推荐吗?

4 个答案:

答案 0 :(得分:13)

有多个swift库可用:

CSVImporter,这是一个适合处理大型csv文件的异步解析器。

let path = "path/to/your/CSV/file"
let importer = CSVImporter<[String]>(path: path)
importer.startImportingRecords { $0 }.onFinish { importedRecords in
    for record in importedRecords {
        // record is of type [String] and contains all data in a line
    }
}

SwiftCSV,这是一个用于OSX和iOS的简单CSV解析库。

let csvURL = NSURL(string: "users.csv")!
var error: NSErrorPointer = nil
let csv = CSV(contentsOfURL: csvURL, error: error)

// Rows
let rows = csv.rows
let headers = csv.headers  //=> ["id", "name", "age"]
let alice = csv.rows[0]    //=> ["id": "1", "name": "Alice", "age": "18"]
let bob = csv.rows[1]      //=> ["id": "2", "name": "Bob", "age": "19"]

// Columns
let columns = csv.columns
let names = csv.columns["name"]  //=> ["Alice", "Bob", "Charlie"]
let ages = csv.columns["age"]    //=> ["18", "19", "20"]

CSwiftV,这是符合rfc4180规范的csv解析器,但据作者说,它全部在内存中,因此不适合大文件。

let inputString = "Year,Make,Model,Description,Price\r\n1997,Ford,E350,descrition,3000.00\r\n1999,Chevy,Venture,another description,4900.00\r\n"
let csv = CSwiftV(String: inputString)

let headers = csv.headers // ["Year","Make","Model","Description","Price"]
let rows = csv.rows 
// [
//  ["1997","Ford","E350","descrition","3000.00"],
//  ["1999","Chevy","Venture","another description","4900.00"]
// ]

答案 1 :(得分:11)

每个答案都要求您安装/下载第三方实用程序,但如果您使用的文件非常简单,或者您在限制第三方代码的公司工作,那么这可能不是最佳选择。

所以我想我会发布令人难以置信的基本的常规CSV文件处理代码,人们可以将其作为基础并根据需要进行简单的CSV处理。

do {
    let file = try String(contentsOf: fileUrl)
    let rows = file.components(separatedBy: .newlines)
    for row in rows {
        let fields = row.replacingOccurrences(of: "\"", with: "").components(separatedBy: ",")
        print(fields)
    }
} catch {
    print(error)
}

这将处理您知道没有引号和逗号作为字段内容的一部分的任何CSV文件,在我的情况下是大多数CSV文件。比这更复杂的东西,我建议使用其他答案中发布的一个库。

我希望这可以节省一些人的打字。

答案 2 :(得分:9)

根据当前最受欢迎的答案,不要使用SwiftCSV。

SwiftCSV目前不处理双引号,因此如果CSV文件中的任何数据中包含换行符或逗号,则SwiftCSV将无效。你可能会浪费宝贵的开发时间来找出它无法正常工作的原因......为了节省你的时间,只需使用另一个库。

CSwiftV 库对我来说效果非常好: https://github.com/Daniel1of1/CSwiftV

它处理引用的文本,换行符,逗号,就像我的数据上的魅力一样。它还具有单元测试并符合rfc4180标准。

答案 3 :(得分:3)

建议使用CSVImporter - 它为您处理引用文字(在RFC 4180之后),甚至处理非常大的文件没有问题。

与其他解决方案相比,它可以同时异步(防止延迟)和逐行读取CSV文件,而不是将整个String加载到内存中(防止内存问题) 。最重要的是,易于使用并提供美丽的回调,用于指示失败,进度,完成甚至数据映射,如果您愿意的话。

最简单的使用方法就是这个(给你每一行作为一个字符串数组):

let path = "path/to/your/CSV/file"
let importer = CSVImporter<[String]>(path: path)
importer.startImportingRecords { $0 }.onFinish { importedRecords in
    for record in importedRecords {
        // record is of type [String] and contains all data in a line
    }
}

利用更复杂的功能,例如数据映射和进度回调:

let path = "path/to/Hogwarts/students"
let importer = CSVImporter<Student>(path: path)
importer.startImportingRecords { recordValues -> Student in

    // define your data mapping here
    return Student(firstName: recordValues[0], lastName: recordValues[1])

}.onProgress { importedDataLinesCount in

    // use this to indicate progress
    print("\(importedDataLinesCount) lines were already imported.")

}.onFinish { importedRecords in
    for student in importedRecords {
        // now importedRecords is an array of Student objects
    }
}