我正在使用Swift 4.2编写iOS应用程序
来自服务器的响应是一个字符串,其值由管道符“|”分隔。它包含许多行值。我想把它拆分成一个子数组。
响应示例:
“001 |苹果|红色| 002 |香蕉|黄色| 003 |葡萄|紫色”
对于此示例,输出应该是包含3个上述水果数组的数组。如果我使用response.componentsSeparatedByString("|")
它会给我一个包含9个元素的数组,这是我不想要的。如果我考虑上面的例子,我需要的是一个包含3个元素的3个数组的数组。
预期产出:
[[001, "apple", "red"], [002, "banana", "yellow"], [003, "grapes", "purple"]]
如果我得到了你想要收到的结果,那么这段代码可以满足你的需求:
extension Array {
func chunked(into size: Int) -> [[Element]] {
return stride(from: 0, to: self.count, by: size).map {
Array(self[$0 ..< Swift.min($0 + size, self.count)])
}
}
}
let src = "001|apple|red|002|banana|yellow|003|grapes|purple"
let result = src.split(separator: "|").map(String.init).chunked(into: 3)
// result = [["001", "apple", "red"], ["002", "banana", "yellow"], ["003", "grapes", "purple"]]
如果您知道所得子阵列的预期大小,这将有效
你也可以从最后一行中删除.map(String.init)
,如果数组元素的类型为String.SubSequence
就可以了
|
字符拆分字符串let input = "001|apple|red|002|banana|yellow|003|grapes|purple"
let result: [[String]] = input
.split(separator: "|")
.reduce(into: []) { result, string in
guard let _ = Int(string) else {
result[result.count - 1].append(String(string))
return
}
result.append([])
}
/// result: [["apple", "red"], ["banana", "yellow"], ["grapes", "purple"]]
如果你想要持久化001
,那么将result.append([])
改为result.append([String(string)])
:
[["001", "apple", "red"], ["002", "banana", "yellow"], ["003", "grapes", "purple"]]
此解决方案期望您的字符串将以数字开头或否则崩溃。 如果您不能保证您的字符串以数字开头,那么您需要在保护块中手动检查该数组是否为空。
基本方式
let str = "001|apple|red|002|banana|yellow|003|grapes|purple"
let components = str.components(separatedBy: "|")
let chunkSize = 3
let loopCount = components.count/chunkSize
var packages: [Array<String>] = []
for index in 0..<loopCount {
/// Starting index
let numIndex = index * chunkSize
/// Get the subarray of range
let package = Array(components[numIndex..<(numIndex+chunkSize)])
packages.append(package)
}
print(packages)
输出:
[[“001”,“apple”,“red”],[“002”,“banana”,“yellow”],[“003”,“grape”,“purple”]]
有了正则表达式,你可以做这样的事情,感谢OOPer's extension
添加一个字符串扩展,根据正则表达式模式拆分字符串。
extension String {
func split(usingRegex pattern: String) -> [String] {
//### Crashes when you pass invalid `pattern`
let regex = try! NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: self, range: NSRange(0..<utf16.count))
let ranges = [startIndex..<startIndex] + matches.map{Range($0.range, in: self)!} + [endIndex..<endIndex]
return (0...matches.count).map { String(self[ranges[$0].lowerBound..<ranges[$0+1].lowerBound]) }
}
}
然后根据连续模式[0-9]{3}
3数字拆分字符串。
let str = "001|apple|red|002|banana|yellow|003|grapes|purple|004|this|is|a|test|one|005|so|is|this"
let pattern = "[0-9]{3}"
let result = str.split(usingRegex: pattern)
var all:[[String]] = []
for row in result {
let split = row.split(separator: "|").map({ (substring) in
return String(substring)
})
if split.count != 0 {
all.append(split)
}
}
dump(all)
我在操场上测试了这个并得到了以下结果:
▿ 5 elements
▿ 3 elements
- "001"
- "apple"
- "red"
▿ 3 elements
- "002"
- "banana"
- "yellow"
▿ 3 elements
- "003"
- "grapes"
- "purple"
▿ 6 elements
- "004"
- "this"
- "is"
- "a"
- "test"
- "one"
▿ 4 elements
- "005"
- "so"
- "is"
- "this"
如果您决定要从结果数组中排除ID,则可以修改扩展名返回到以下内容:
return (0...matches.count).map { String(self[ranges[$0].upperBound..<ranges[$0+1].lowerBound]) }
这将切换返回范围以使用upperBound
而不是lowerBound
您可以使用byWords选项在范围内使用String方法enumerateSubstrings,检查字符串是否为整数,如果是,则将带有该字符串的新数组附加到结果,否则将该字附加到最后的结果数组:
let string = "001|apple|red|002|banana|yellow|003|grapes|purple"
var result: [[Substring]] = []
string.enumerateSubstrings(in: string.startIndex..., options: .byWords) { _, range, _, _ in
let word = string[range]
if let _ = Int(word) {
result.append([word])
// or just a new empty array
// result.append([])
} else {
result[result.index(before: result.endIndex)].append(word)
}
}
print(result) // "[["001", "apple", "red"], ["002", "banana", "yellow"], ["003", "grapes", "purple"]]\n"
好的你可以递归地做
let input = "001|apple|red|002|banana|yellow|003|grapes|purple"
let array = input.components(separatedBy: "|")
// Get Chunks from array
extension Array {
func getFirstElements(upTo position: Int) -> Array<Element> {
let arraySlice = self[0 ..< position]
return Array(arraySlice)
}
}
func recersivelyGetArray (array:[String], slice:inout [[String]]) {
guard !array.isEmpty else{
return
}
var copyArray = array
var chunkSize = 3
if array.count >= 3 {
chunkSize = 3
} else {
chunkSize = array.count
}
let threeElements = copyArray.getFirstElements(upTo: chunkSize)
slice.append(threeElements)
copyArray.removeFirst(chunkSize)
recersivelyGetArray(array: copyArray, slice: &slice)
}
var inoutResult = [[String]]()
recersivelyGetArray(array: array, slice: &inoutResult)
print(inoutResult)
产量
案例1输入
let input = "001|apple|red|002|banana|yellow|003|grapes|purple"
[[“001”,“apple”,“red”],[“002”,“banana”,“yellow”],[“003”,“grape”,“purple”]]
案例2输入
let input = "001|apple|red|002|banana|yellow|003|grapes"
[[“001”,“apple”,“red”],[“002”,“banana”,“yellow”],[“003”,“grape”]]