How add separator to string at every N characters in swift? How add separator to string at every N characters in swift? ios ios

How add separator to string at every N characters in swift?


Swift 5.2 • Xcode 11.4 or later

extension Collection {    func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence<SubSequence,Index> {        sequence(state: startIndex) { start in            guard start < self.endIndex else { return nil }            let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex            defer { start = end }            return self[start..<end]        }    }    func every(n: Int) -> UnfoldSequence<Element,Index> {        sequence(state: startIndex) { index in            guard index < endIndex else { return nil }            defer { index = self.index(index, offsetBy: n, limitedBy: endIndex) ?? endIndex }            return self[index]        }    }    var pairs: [SubSequence] { .init(unfoldSubSequences(limitedTo: 2)) }}


extension StringProtocol where Self: RangeReplaceableCollection {    mutating func insert<S: StringProtocol>(separator: S, every n: Int) {        for index in indices.every(n: n).dropFirst().reversed() {            insert(contentsOf: separator, at: index)        }    }    func inserting<S: StringProtocol>(separator: S, every n: Int) -> Self {        .init(unfoldSubSequences(limitedTo: n).joined(separator: separator))    }}


Testing

let str = "112312451"let final0 = str.unfoldSubSequences(limitedTo: 2).joined(separator: ":")print(final0)      // "11:23:12:45:1"let final1 = str.pairs.joined(separator: ":")print(final1)      // "11:23:12:45:1"let final2 = str.inserting(separator: ":", every: 2)print(final2)      // "11:23:12:45:1\n"var str2 = "112312451"str2.insert(separator: ":", every: 2)print(str2)   // "11:23:12:45:1\n"var str3 = "112312451"str3.insert(separator: ":", every: 3)print(str3)   // "112:312:451\n"var str4 = "112312451"str4.insert(separator: ":", every: 4)print(str4)   // "1123:1245:1\n"


I'll go for this compact solution (in Swift 4) :

let s = "11231245"let r = String(s.enumerated().map { $0 > 0 && $0 % 2 == 0 ? [":", $1] : [$1]}.joined())

You can make an extension and parameterize the stride and the separator so that you can use it for every value you want (In my case, I use it to dump 32-bit space-operated hexadecimal data):

extension String {    func separate(every stride: Int = 4, with separator: Character = " ") -> String {        return String(enumerated().map { $0 > 0 && $0 % stride == 0 ? [separator, $1] : [$1]}.joined())    }}

In your case this gives the following results:

let x = "11231245"print (x.separate(every:2, with: ":")$ 11:23:12:45


Short and simple, add a let or two if you want

extension String {    func separate(every: Int, with separator: String) -> String {        return String(stride(from: 0, to: Array(self).count, by: every).map {            Array(Array(self)[$0..<min($0 + every, Array(self).count)])        }.joined(separator: separator))    }}

let a = "separatemepleaseandthankyou".separate(every: 4, with: " ")

a is

sepa rate mepl ease andt hank you