我有一个包含以下格式的数据的文本。
AYGA:GKA:GOROKA:GOROKA:PAPUA NEW GUINEA:06:04:54:S:145:23:30:E:5282
AYLA:LAE::LAE:PAPUA NEW GUINEA:00:00:00:U:00:00:00:U:0000
AYMD:MAG:MADANG:MADANG:PAPUA NEW GUINEA:05:12:25:S:145:47:19:E:0020
如何分隔用冒号(“:”)区分的每个项目以及如何将每个部分加载到数组中,如下例所示?
var array1 = ["AYGA", "AYLA", "AYMD"]
var array2 = ["GKA", "LAE", "MAG"]
var array3 = ["GOROKA", "", "MADANG"]
var array4 = ["GOROKA", "LAE", "MADANG"]
var array5 = ["PAPUA NEW GUINEA", "PAPUA NEW GUINEA", "PAPUA NEW GUINEA"]
var array6 = ["06", "00", "05"]
var array7 = ["04", "00", "12"]
var array8 = ["54", "00", "25"]
var array9 = ["S", "U", "S"]
var array10 = ["145", "00", "145"]
var array11 = ["23", "00", "47"]
var array12 = ["30", "00", "19"]
var array13 = ["E", "U", "E"]
var array14 = ["5282", "0000", "0020"]
答案 0 :(得分:8)
您要做的事情称为转置。转动一个看起来像的数组:
[[1, 2, 3], [4, 5, 6]]
进入一个看起来像这样的数组:
[[1, 4], [2, 5], [3, 6]]
要做到这一点,让我们定义一个用于转置的通用函数并将其应用于您的问题
// Import the text file from the bundle
guard
let inputURL = NSBundle.mainBundle().URLForResource("input", withExtension: "txt"),
let input = try? String(contentsOfURL: inputURL)
else { fatalError("Unable to get data") }
// Convert the input string into [[String]]
let strings = input.componentsSeparatedByString("\n").map { (string) -> [String] in
string.componentsSeparatedByString(":")
}
// Define a generic transpose function.
// This is the key to the solution.
public func transpose<T>(input: [[T]]) -> [[T]] {
if input.isEmpty { return [[T]]() }
let count = input[0].count
var out = [[T]](count: count, repeatedValue: [T]())
for outer in input {
for (index, inner) in outer.enumerate() {
out[index].append(inner)
}
}
return out
}
// Transpose the strings
let results = transpose(strings)
您可以使用
查看转置的结果for result in results {
print("\(result)")
}
生成(为您的示例)
["AYGA", "AYLA", "AYMD"]
["GKA", "LAE", "MAG"]
["GOROKA", "", "MADANG"]
["GOROKA", "LAE", "MADANG"]
["PAPUA NEW GUINEA", "PAPUA NEW GUINEA", "PAPUA NEW GUINEA"]
["06", "00", "05"]
["04", "00", "12"]
["54", "00", "25"]
["S", "U", "S"]
["145", "00", "145"]
["23", "00", "47"]
["30", "00", "19"]
["E", "U", "E"]
["5282", "0000", "0020"]
这样做的好处是不依赖于你拥有的数组的数量,并且从第一个数组的计数中获取子数组的数量。
您可以download an example playground为此,其中输入作为操场资源中的文件。
答案 1 :(得分:1)
这是另一种替代方案,可以很好地处理不同的换行符,并且不需要任何硬编码来获得正确数量的数组。从第一行读取冒号分隔的组件数。
let input = "AYGA:GKA:GOROKA:GOROKA:PAPUA NEW GUINEA:06:04:54:S:145:23:30:E:5282\nAYLA:LAE::LAE:PAPUA NEW GUINEA:00:00:00:U:00:00:00:U:0000\nAYMD:MAG:MADANG:MADANG:PAPUA NEW GUINEA:05:12:25:S:145:47:19:E:0020"
var arrays: [[String]]?
input.enumerateLines { (line, _) in
let chunks = line.componentsSeparatedByString(":")
if arrays == nil {
arrays = [[String]](count: chunks.count, repeatedValue: [String]())
}
chunks.enumerate().forEach { item in
arrays?[item.index].append(item.element)
}
}
答案 2 :(得分:0)
也许更通用(并且具有类似行为的zip
):
extension Sequence where
Element: Collection,
Element.Index == Int,
Element.IndexDistance == Int
{
public func transposed(prefixWithMaxLength max: Int = .max) -> [[Element.Element]] {
var o: [[Element.Element]] = []
let n = Swift.min(max, self.min{ $0.count < $1.count }?.count ?? 0)
o.reserveCapacity(n)
for i in 0 ..< n {
o.append(map{ $0[i] })
}
return o
}
}
现在我们可以像这样使用它:
[0..<5, 10..<20, 100..<200]
.map(Array.init)
.transposed()
...返回:
[[0, 10, 100], [1, 11, 101], [2, 12, 102], [3, 13, 103], [4, 14, 104]]