【发布时间】:2017-11-21 20:41:11
【问题描述】:
编辑:我需要将 CSV(具有字符串和整数列类型)作为结构数组导入。 不是作为结构的二维数组(答案很好地解释了)。
原始问题(解释不清):
我正在尝试创建一个包含字符串和整数值的二维数组(基于我导入的 CSV 的内容)。这些可以通过它们所在的“列”来识别。有没有办法做到这一点?我知道三种可能的解决方案:
-
将数组声明为
[Any],但我不想这样做,因为我希望它被显式键入 -
通过使用
.flatmap(如How to convert a String (numeric) in a Int array in Swift)让字符串 = "123,456,789" 让 intArray = string.components(separatedBy: ",").flatMap { Int($0) } 但我不希望这样做,因为我的数组的“字符串”列中可能有整数。
-
将我的数组保留为
[String],并将我的“Int”列作为字符串(这是我目前正在做的)。
下面是我正在使用的代码的简化版本。当我尝试将逗号分隔的字符串解析为具有不同值类型的数组时,它会出错。
非常感谢所有帮助...谢谢!
struct MyStruct {
let Str1 : String
let Str2 : String
let Str3 : String
let Str4 : String
let Int1 : Int
}
func csvStringToArray(stringCSV: String) -> [[MyStruct]] {
// create an empty 2-D array to hold the CSV data.
var dataArray: [[MyStruct]] = []
// parse the CSV into rows.
var csvRows: [String] = stringCSV.components(separatedBy: "\n")
print(csvRows)
// ["a,b,c,d,99", "j,k,l,m,98", "w,x,y,z,97", etc]
// append each row (1-D array) to dataArray (filling the 2-D array).
for i in csvRows {
let csvColumns: [MyStruct] = i.components(separatedBy: ",") // Cannot convert value of type '[String]' to specified type '[MyStruct]'
dataArray.append(csvColumns)
print(csvColumns) // this is the output if I set csvColumns: [String]; otherwise it errors out.
// ["a", "b", "c", "d", "99"]
// ["j", "k", "l", "m", "98"]
// ["w", "x", "y", "z", "97"]
// etc...
}
print(dataArray) // again only if csvColumns: [String]
// ["a", "b", "c", "d", "99"], ["j", "k", "l", "m", "98"], ["w", "x", "y", "z", "97"], [etc... ]
return dataArray
}
【问题讨论】:
-
为什么不使用 CSV 解析库?一方面,
components(separatedBy: ",")将通过检测所有转义的逗号(必须将其解析为字符串的一部分,而不是 CSV 结构的一部分)而失败 -
为了简单起见,我试图避免使用第 3 方库。我知道我的数据将始终遵循相同的格式(我确定还有其他问题,但您提到的具体问题不会影响我)。即使在这种情况下使用一个会更好吗?
-
我认为重新发明轮子而不是使用已经免费提供的东西并不简单。需求变化,数据格式变化,所以我不会浪费时间为如此有限的 CSV 子集编写解析器。
-
点了。进一步思考,我喜欢
components(separatedBy: ","),因为我可以很容易地看到它是如何工作的。以前没有使用过图书馆,这对我来说更像是一个黑匣子。我需要加快速度的许多事情之一。 -
那么,这绝对是要解决的问题。黑匣子很好。您越频繁地生成功能良好的代码而无需关心其内部结构越好。少即是多。