在swift中解析CSV文件

cha*_*shu 4 csv parsing ios swift

我在github的帮助下将数据从csv文件解析为字典.
解析后我得到这种类型的字典: -

{
"" = "";
"\"barred_date\"" = "\"\"";
"\"company_id\"" = "\"1\"";
"\"company_name\"" = "\"\"";
"\"contact_no\"" = "\"1234567890\"";
"\"created_date\"" = "\"2015-06-01 12:43:11\"";
"\"current_project\"" = "\"111\"";
"\"designation\"" = "\"Developer\"";
"\"doj\"" = "\"2015-06-01 00:00:00\"";
"\"fin_no\"" = "\"ABC001\"";
"\"first_name\"" = "\"sssd\"";
"\"last_name\"" = "\"dd\"";
"\"project_name\"" = "\"Project 1\"";
"\"qr_code\"" = "\"12345678\"";
"\"resignation_date\"" = "\"\"";
"\"status\"" = "\"1\"";
"\"work_permit_no\"" = "\"ssdda11\"";
"\"worker_id\"" = "\"1\"";
"\"worker_image\"" = "\"assets/uploads/workers/eb49364ca5c5d22f11db2e3c84ebfce6.jpeg\"";
"\"worker_image_thumb\"" = "\"assets/uploads/workers/thumbs/eb49364ca5c5d22f11db2e3c84ebfce6.jpeg\"";}
Run Code Online (Sandbox Code Playgroud)

如何将其转换为简单字典.我需要这样的数据"company_id"="1"

谢谢

n13*_*n13 7

请改用CSwiftV解析器:https://github.com/Daniel1of1/CSwiftV

它实际上处理引用的文本,因此它处理文本中的换行符和逗号.SwiftCSV花了我一些时间,因为它没有处理.但我确实了解了CSV格式并对其进行了解析;)


Jee*_*hut 6

建议使用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
    }
}
Run Code Online (Sandbox Code Playgroud)

利用更复杂的功能,例如标题结构支持,如下所示:

// given this CSV file content
firstName,lastName
Harry,Potter
Hermione,Granger
Ron,Weasley

// you can import data in Dictionary format
let path = "path/to/Hogwarts/students"
let importer = CSVImporter<[String: String]>(path: path)
importer.startImportingRecords(structure: { (headerValues) -> Void in

    // use the header values CSVImporter has found if needed
    print(headerValues) // => ["firstName", "lastName"]

}) { $0 }.onFinish { importedRecords in

    for record in importedRecords {
        // a record is now a Dictionary with the header values as keys
        print(record) // => e.g. ["firstName": "Harry", "lastName": "Potter"]
        print(record["firstName"]) // prints "Harry" on first, "Hermione" on second run
        print(record["lastName"]) // prints "Potter" on first, "Granger" on second run
    }
}
Run Code Online (Sandbox Code Playgroud)


Wil*_*lC7 5

将 CSV 解析为二维字符串数组(行和列)

func parseCsv(_ data: String) -> [[String]] {
    // data: String = contents of a CSV file.
    // Returns: [[String]] = two-dimension array [rows][columns].
    // Data minimum two characters or fail.
    if data.count < 2 {
        return []
    }
    var a: [String] = [] // Array of columns.
    var index: String.Index = data.startIndex
    let maxIndex: String.Index = data.index(before: data.endIndex)
    var q: Bool = false // "Are we in quotes?"
    var result: [[String]] = []
    var v: String = "" // Column value.
    while index < data.endIndex {
        if q { // In quotes.
            if (data[index] == "\"") {
                // Found quote; look ahead for another.
                if index < maxIndex && data[data.index(after: index)] == "\"" {
                    // Found another quote means escaped.
                    // Increment and add to column value.
                    data.formIndex(after: &index)
                    v += String(data[index])
                } else {
                    // Next character not a quote; last quote not escaped.
                    q = !q // Toggle "Are we in quotes?"
                }
            } else {
                // Add character to column value.
                v += String(data[index])
            }
        } else { // Not in quotes.
            if data[index] == "\"" {
                // Found quote.
                q = !q // Toggle "Are we in quotes?"
            } else if data[index] == "\r" || data[index] == "\r\n" {
                // Reached end of line.
                // Column and row complete.
                a.append(v)
                v = ""
                result.append(a)
                a = []
            } else if data[index] == "," {
                // Found comma; column complete.
                a.append(v)
                v = ""
            } else {
                // Add character to column value.
                v += String(data[index])
            }
        }
        if index == maxIndex {
            // Reached end of data; flush.
            if v.count > 0 || data[data.index(before: index)] == "," {
                a.append(v)
            }
            if a.count > 0 {
                result.append(a)
            }
            break
        }
        data.formIndex(after: &index) // Increment.
    }
    return result
}
Run Code Online (Sandbox Code Playgroud)

使用 CSV 数据调用上面的方法

let dataArray: [[String]] = parseCsv(yourStringOfCsvData)
Run Code Online (Sandbox Code Playgroud)

然后提取标题行

let dataHeader = dataArray.removeFirst()
Run Code Online (Sandbox Code Playgroud)

我假设您需要一组字典(大多数电子表格数据包含多行,而不仅仅是一行)。下一个循环就是为了这个。但是,如果您只需要单个字典中的一行(和键的标题),您可以研究下面的内容并了解如何到达那里。

    var da: [Dictionary<String, String>] = [] // Array of dictionaries.
    for row in dataArray {
        for (index, column) in row.enumerated() {
            var d: Dictionary<String, String> = Dictionary()
            d.updateValue(column, forKey: dataHeader[index])
            da.append(d)
        }
    }
Run Code Online (Sandbox Code Playgroud)