The solution with a while loop is actually a bit more flexible than the one with the stride. Here is a slight update (Swift 5) of Adam's answer:
extension String {
func split(len: Int) -> [String] {
var currentIndex = 0
var array = [String]()
let length = self.count
while currentIndex < length {
let startIndex = index(self.startIndex, offsetBy: currentIndex)
let endIndex = index(startIndex, offsetBy: len, limitedBy: self.endIndex) ?? self.endIndex
let substr = String( self[startIndex...endIndex] )
array.append(substr)
currentIndex += len
}
return array
}
}
We can generalise it to take a an array of Ints instead of a single Int. So that we can split a string into substrings of various lengths like so:
extension String {
func split(len: [Int]) -> [String] {
var currentIndex = 0
var array = [String]()
let length = self.count
var i = 0
while currentIndex < length {
let startIndex = index(self.startIndex, offsetBy: currentIndex)
let endIndex = index(startIndex, offsetBy: len[i], limitedBy: self.endIndex) ?? self.endIndex
let substr = String( self[startIndex..<endIndex] )
array.append(substr)
currentIndex += len[i]
i += 1
}
return array
}
}
Usage:
func testSplitString() throws {
var retVal = "Hello, World!".split(len: [6, 1, 6])
XCTAssert( retVal == ["Hello,", " ", "World!"] )
retVal = "Hello, World!".split(len: [5, 2, 5, 1])
XCTAssert( retVal == ["Hello", ", ", "World", "!"] )
retVal = "hereyouare".split(len: [4, 3, 3])
XCTAssert( retVal == ["here", "you", "are"] )
}