Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 ?

like image 929
Bolo Avatar asked Dec 24 '15 14:12

Bolo


People also ask

How do I separate a string from a character in Swift?

You can use components(separatedBy:) method to divide a string into substrings by specifying string separator. let str = "Hello! Swift String."

Does \n work in Swift?

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.

How do I split a string into two strings in Swift?

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+?


2 Answers

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 
like image 36
Stéphane de Luca Avatar answered Sep 28 '22 03:09

Stéphane de Luca


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" 
like image 66
Leo Dabus Avatar answered Sep 28 '22 01:09

Leo Dabus