swift 3.1如何从CSV获取数组或字典
我如何使用这种CSV文件中的数据?或者,如何打印“inside”列的第2行值并将其分配给属性/实体 我有这样的文件,我从excel文件转换成数字,我想抓住每列的数据,并使用它们 以数字形式打开的原始CSV文件: 我得到的控制台输出: 使用这种方法:swift 3.1如何从CSV获取数组或字典,csv,parsing,swift3,Csv,Parsing,Swift3,我如何使用这种CSV文件中的数据?或者,如何打印“inside”列的第2行值并将其分配给属性/实体 我有这样的文件,我从excel文件转换成数字,我想抓住每列的数据,并使用它们 以数字形式打开的原始CSV文件: 我得到的控制台输出: 使用这种方法: func readDataFromCSV(fileName:String, fileType: String)-> String!{ guard let filepath = Bundle.main.path(forReso
func readDataFromCSV(fileName:String, fileType: String)-> String!{
guard let filepath = Bundle.main.path(forResource: fileName, ofType: fileType)
else {
return nil
}
do {
var contents = try String(contentsOfFile: filepath, encoding: .utf8)
contents = cleanRows(file: contents)
return contents
} catch {
print("File Read Error for file \(filepath)")
return nil
}
}
func cleanRows(file:String)->String{
var cleanFile = file
cleanFile = cleanFile.replacingOccurrences(of: "\r", with: "\n")
cleanFile = cleanFile.replacingOccurrences(of: "\n\n", with: "\n")
// cleanFile = cleanFile.replacingOccurrences(of: ";;", with: "")
// cleanFile = cleanFile.replacingOccurrences(of: ";\n", with: "")
return cleanFile
}
感谢Jens Meder的解决方案
使用
func csv(data: String) -> [[String]] {
var result: [[String]] = []
let rows = data.components(separatedBy: "\n")
for row in rows {
let columns = row.components(separatedBy: ";")
result.append(columns)
}
return result
}
在viewDidLoad中
var data = readDataFromCSV(fileName: kCSVFileName, fileType: kCSVFileExtension)
data = cleanRows(file: data!)
let csvRows = csv(data: data!)
print(csvRows[1][1]) // UXM n. 166/167
您要做的是将字符串分为行,然后分为列(基本上是一个二维字符串数组)。Swift已经提供了
String
structs上的方法
func csv(data: String) -> [[String]] {
var result: [[String]] = []
let rows = data.components(separatedBy: "\n")
for row in rows {
let columns = row.components(separatedBy: ";")
result.append(columns)
}
return result
}
然后,您可以通过以下方式访问任何值:
var data = readDataFromCSV(fileName: kCSVFileName, fileType: kCSVFileExtension)
data = cleanRows(file: data)
let csvRows = csv(data: data)
print(csvRows[1][1]) //UXM n. 166/167.
Swift 4 有时CSV文件更复杂,例如特殊字符(例如逗号),值用双引号括起来,如下所示:
Hello, "Complicated String, with a comma inside", 123
在这种情况下,我使用:
let dataString: String! = String.init(data: data!, encoding: .utf8)
var items: [(String, String, String)] = []
let lines: [String] = dataString.components(separatedBy: NSCharacterSet.newlines) as [String]
for line in lines {
var values: [String] = []
if line != "" {
if line.range(of: "\"") != nil {
var textToScan:String = line
var value:NSString?
var textScanner:Scanner = Scanner(string: textToScan)
while textScanner.string != "" {
if (textScanner.string as NSString).substring(to: 1) == "\"" {
textScanner.scanLocation += 1
textScanner.scanUpTo("\"", into: &value)
textScanner.scanLocation += 1
} else {
textScanner.scanUpTo(",", into: &value)
}
values.append(value! as String)
if textScanner.scanLocation < textScanner.string.count {
textToScan = (textScanner.string as NSString).substring(from: textScanner.scanLocation + 1)
} else {
textToScan = ""
}
textScanner = Scanner(string: textToScan)
}
// For a line without double quotes, we can simply separate the string
// by using the delimiter (e.g. comma)
} else {
values = line.components(separatedBy: ",")
}
// Put the values into the tuple and add it to the items array
let item = (values[0], values[1], values[2])
items.append(item)
print(item.1)
print(item.2)
print(item.3)
}
}
let dataString:String!=String.init(数据:data!,编码:.utf8)
变量项:[(字符串,字符串,字符串)]=[]
将行:[String]=dataString.components(分隔符:NSCharacterSet.newlines)设为[String]
排队{
变量值:[字符串]=[]
如果行!“”{
如果line.range(of:“\”)!=nil{
var textToScan:String=line
var值:NSString?
变量textScanner:Scanner=Scanner(字符串:textToScan)
而textScanner.string!“”{
如果(textScanner.string作为NSString)。子字符串(到:1)=“\”“{
textScanner.scanLocation+=1
textScanner.Scanup(“\”,输入:&值)
textScanner.scanLocation+=1
}否则{
textScanner.Scanup(“,”到:&值)
}
values.append(value!作为字符串)
如果textScanner.scanLocation
它是用Swift 4写的,原文来自 这是swift 4.2的CSV文件,地址为20181208
var dataArray : [String] = []
if let path = Bundle.main.path(yourfile: "svenskaidiom", ofType: "csv")
{
dataArray = []
let url = URL(fileURLWithPath: path)
do {
let data = try Data(contentsOf: url)
let dataEncoded = String(data: data, encoding: .utf8)
if let dataArr = dataEncoded?.components(separatedBy: "\r\n").map({ $0.components(separatedBy: ";") })
{
for line in dataArr
{
dataArray?.append(line)
}
}
}
catch let jsonErr {
print("\n Error read CSV file: \n ", jsonErr)
}
}
Swift 5.0
.scanLocaion和.scanUpTo()在iOS13中被弃用
func openCSV(fileName:String, fileType: String)-> String!{
guard let filepath = Bundle.main.path(forResource: fileName, ofType: fileType)
else {
return nil
}
do {
let contents = try String(contentsOfFile: filepath, encoding: .utf8)
return contents
} catch {
print("File Read Error for file \(filepath)")
return nil
}
}
func parseCSV(){
let dataString: String! = openCSV(fileName: "MeislinDemo", fileType: "csv")
var items: [(String, String, String)] = []
let lines: [String] = dataString.components(separatedBy: NSCharacterSet.newlines) as [String]
for line in lines {
var values: [String] = []
if line != "" {
if line.range(of: "\"") != nil {
var textToScan:String = line
var value:String?
var textScanner:Scanner = Scanner(string: textToScan)
while !textScanner.isAtEnd {
if (textScanner.string as NSString).substring(to: 1) == "\"" {
textScanner.currentIndex = textScanner.string.index(after: textScanner.currentIndex)
value = textScanner.scanUpToString("\"")
textScanner.currentIndex = textScanner.string.index(after: textScanner.currentIndex)
} else {
value = textScanner.scanUpToString(",")
}
values.append(value! as String)
if !textScanner.isAtEnd{
let indexPlusOne = textScanner.string.index(after: textScanner.currentIndex)
textToScan = String(textScanner.string[indexPlusOne...])
} else {
textToScan = ""
}
textScanner = Scanner(string: textToScan)
}
// For a line without double quotes, we can simply separate the string
// by using the delimiter (e.g. comma)
} else {
values = line.components(separatedBy: ",")
}
// Put the values into the tuple and add it to the items array
let item = (values[0], values[1], values[2])
items.append(item)
print(item.0)
print(item.1)
print(item.2)
}
}
}
有什么问题吗?您似乎已经读取了数据。是的,我读取了数据,但我只有一个长字符串,如何打印“inside”的第2行值“列并将其分配给属性/实体?是否尝试搜索堆栈溢出?”?你真的认为你是第一个想要将CSV文件拆分成组件的人吗?很明显,可能是重复的!,事实上,这段代码是我搜索的结果,也是我的另一个问题,但很多人向我解释说CSV很难操作,我最好更改文件扩展名,问题是这是不可能的。而且,所有的解决方案都是针对不同的CSV文件定制的,我不知道如何解决这种问题。最后,swift版本和答案之间的设计模式发生了很大变化,因此我发现将CSV转换为字典或数组的主要步骤甚至很难理解。为了您的帮助,我用您的代码在我的问题中添加了一个测试,但是我想我不明白在数据中放什么:你能检查一下我是否误解了什么吗?我使用的
是指你的readdatafromsv
方法的结果。它基本上是您读入字符串的csv文件的内容。完成!我应该使用cswRows,用你的解决方案更新整个答案,谢谢你的帮助!如果在值中有特殊字符,例如,那么这将不起作用其中一个字符串中的代码>。还有更多的逃跑规则。最好找到一个成熟的库来为您解析它。这个解析器(和本页上的任何解析器一样)是有缺陷的。它以新行分隔行开始,这是一个错误的假设。csv文件在双引号中时可能包含一个换行符作为其值。因此,唯一的方法是从一开始就正确地解析,使用一个迷你状态机,不要假设任何东西这个解决方案也不起作用。如果一个值内部有一个换行符(如果该值周围有双引号,这是可能的),那么这也将无法正确解析。它也是不可伸缩的。这个解决方案假设我们只有3列,但是如果您使用的数据集是30列,那么您不应该定义30个元素元组