How can I split the given String
in Swift into groups with given length, reading from right to left?
For example, I have string 123456789
and group length of 3. The the string should be divided into 3 groups: 123
, 456
, 789
. String 1234567
will be divided into 1
, 234
, 567
So, can you write some nice code in Swift:
func splitedString(string: String, length: Int) -> [String] {
}
BTW tried function split()
, but as I understand it works only with finding some symbol
Swift 4
I adapted the answer given by cafedeichi to operate either left-to-right or right-to-left depending on a function parameter, so it's more versatile.
extension String {
/// Splits a string into groups of `every` n characters, grouping from left-to-right by default. If `backwards` is true, right-to-left.
public func split(every: Int, backwards: Bool = false) -> [String] {
var result = [String]()
for i in stride(from: 0, to: self.count, by: every) {
switch backwards {
case true:
let endIndex = self.index(self.endIndex, offsetBy: -i)
let startIndex = self.index(endIndex, offsetBy: -every, limitedBy: self.startIndex) ?? self.startIndex
result.insert(String(self[startIndex..<endIndex]), at: 0)
case false:
let startIndex = self.index(self.startIndex, offsetBy: i)
let endIndex = self.index(startIndex, offsetBy: every, limitedBy: self.endIndex) ?? self.endIndex
result.append(String(self[startIndex..<endIndex]))
}
}
return result
}
}
Example:
"abcde".split(every: 2) // ["ab", "cd", "e"]
"abcde".split(every: 2, backwards: true) // ["a", "bc", "de"]
"abcde".split(every: 4) // ["abcd", "e"]
"abcde".split(every: 4, backwards: true) // ["a", "bcde"]
func split(every length:Int) -> [Substring] {
guard length > 0 && length < count else { return [suffix(from:startIndex)] }
return (0 ... (count - 1) / length).map { dropFirst($0 * length).prefix(length) }
}
func split(backwardsEvery length:Int) -> [Substring] {
guard length > 0 && length < count else { return [suffix(from:startIndex)] }
return (0 ... (count - 1) / length).map { dropLast($0 * length).suffix(length) }.reversed()
}
Tests:
XCTAssertEqual("0123456789".split(every:2), ["01", "23", "45", "67", "89"])
XCTAssertEqual("0123456789".split(backwardsEvery:2), ["01", "23", "45", "67", "89"])
XCTAssertEqual("0123456789".split(every:3), ["012", "345", "678", "9"])
XCTAssertEqual("0123456789".split(backwardsEvery:3), ["0", "123", "456", "789"])
XCTAssertEqual("0123456789".split(every:4), ["0123", "4567", "89"])
XCTAssertEqual("0123456789".split(backwardsEvery:4), ["01", "2345", "6789"])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With