I have a string which contains binary digits. How to separate it in to pairs of digits?
Suppose the string is:
let x = "11231245"
I want to add a separator such as ":" (i.e., a colon) after each 2 characters.
I would like the output to be:
"11:23:12:45"
How could I do this in Swift ?
You can use components(separatedBy:) method to divide a string into substrings by specifying string separator. let str = "Hello! Swift String."
By default Swift strings can't span more than one line. One simple way around this is to use the new line character \n , but that only works for strings that are displayed – if you're just trying to format your string nicely, you should use multi-line strings instead.
Xcode 8.1 / Swift 3.0.1 Attention (Swift 4): If you have a string like let a="a,,b,c" and you use a. split(separator: ",") you get an array like ["a", "b", c"] by default. This can be changed using omittingEmptySubsequences: false which is true by default. Any multi-character splits in Swift 4+?
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
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 < endIndex else { return nil } let end = index(start, offsetBy: maxLength, limitedBy: endIndex) ?? 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 { formIndex(&index, offsetBy: n, limitedBy: 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"
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