2015-12-24 18 views
10

Ho una stringa che contiene cifre binarie. Come separarlo in coppie di cifre?Come aggiungere separatore alla stringa ad ogni N caratteri in rapido?

Supponiamo che la stringa è:

let x = "11231245" 

voglio aggiungere un separatore come ad esempio ":" (vale a dire, due punti) dopo ogni 2 caratteri.

vorrei l'output di essere:

"11:23:12:45" 

Come potrei fare questo in Swift?

+0

Per la cronaca e il tuo vantaggio in futuro, ':' è un "due punti". "Virgola" significa ','. – Arc676

+0

cosa hai provato finora? nota che l'unica linea di codice che hai fornito non è in realtà nemmeno un codice valido – luk2302

risposta

21

È possibile utilizzare stride(from:, to:, by:) per iterare ogni 2 caratteri nella stringa e utilizzare semplicemente join(with: separator) per concatenare nuovamente la stringa.

Swift 4

extension String { 
    var pairs: [String] { 
     var result: [String] = [] 
     let characters = Array(self) 
     stride(from: 0, to: count, by: 2).forEach { 
      result.append(String(characters[$0..<min($0+2, count)])) 
     } 
     return result 
    } 
    mutating func insert(separator: String, every n: Int) { 
     self = inserting(separator: separator, every: n) 
    } 
    func inserting(separator: String, every n: Int) -> String { 
     var result: String = "" 
     let characters = Array(self) 
     stride(from: 0, to: count, by: n).forEach { 
      result += String(characters[$0..<min($0+n, count)]) 
      if $0+n < count { 
       result += separator 
      } 
     } 
     return result 
    } 
} 

Swift 3

extension String { 
    var pairs: [String] { 
     var result: [String] = [] 
     let characters = Array(self.characters) 
     stride(from: 0, to: characters.count, by: 2).forEach { 
      result.append(String(characters[$0..<min($0+2, characters.count)])) 
     } 
     return result 
    } 
    mutating func insert(separator: String, every n: Int) { 
     self = inserting(separator: separator, every: n) 
    } 
    func inserting(separator: String, every n: Int) -> String { 
     var result: String = "" 
     let characters = Array(self.characters) 
     stride(from: 0, to: characters.count, by: n).forEach { 
      result += String(characters[$0..<min($0+n, characters.count)]) 
      if $0+n < characters.count { 
       result += separator 
      } 
     } 
     return result 
    } 
} 

Testing

let str1 = "112312451" 

let finalString1 = str1.pairs.joined(separator: ":") // "11:23:12:45:1" 
print(str1) // "112312451\n" 

let finalString2 = str1.inserting(separator: ":", every: 2) // "11:23:12:45:1" 
print(str1) // "112312451\n" 


var str2 = "112312451" 
str2.insert(separator: ":", every: 2) 
print(str2) // "11:23:12:45:1\n" 
+0

@LeoDabus Hai scritto queste estensioni? Se sì, potresti aiutare con quello che sto cercando di fare? Sto cercando di inserire un "|" ogni 70 caratteri ma solo se quel settantesimo carattere è uno spazio. Se non lo è, cammina all'indietro finché non trova uno spazio. In pratica sto usando questo come un nuovo generatore di linee. Non riesco a capire come fare per farlo e ho provato molti modi diversi. – TheValyreanGroup

+0

Sì, li ho scritti tutti. Sentiti libero di postare il tuo approccio al problema e cosa è andato storto in una nuova domanda e darò un'occhiata a questo. –

+0

@LeoDabus Grande, dai un'occhiata qui. http: // StackOverflow.it/questions/43005306/insert-character-in-string-every-nth-index-unless-its-a-space – TheValyreanGroup

6

Il mio tentativo di quel codice sarebbe:

func insert(seperator: String, afterEveryXChars: Int, intoString: String) -> String { 
    var output = "" 
    intoString.characters.enumerate().forEach { index, c in 
     if index % afterEveryXChars == 0 && index > 0 { 
      output += seperator 
     } 
     output.append(c) 
    } 
    return output 
} 

insert(":", afterEveryXChars: 2, intoString: "11231245") 

quali uscite

11: 23: 12: 45

+0

Ti spiace se modifico il tuo codice? Non è necessario utilizzare un contatore, è possibile utilizzare enumerate(). È inoltre possibile aggiungere una condizione aggiuntiva (indice> 0) per aggiungere il separatore per poter eliminare il metodo dropFirst –

+1

inString.characters.enumerate(). ForEach {index, c in if index% afterEveryXChars == 0 && indice> 0 {... –

+0

@LeoDabus no, vai avanti - stai ancora giocando con esso? : P – luk2302

6
let y = String(
    x.characters.enumerate().map() { 
     $0.index % 2 == 0 ? [$0.element] : [$0.element, ":"] 
    }.flatten() 
) 
+1

quel codice lascia un 'iling ':', prova ad aggiungere il ':' davanti a '$ 0.element' se e solo se non lo sei al primo personaggio. – luk2302

+0

aggiungi semplicemente .flatten(). DropLast() –

+1

La richiesta era "dopo ogni 2 caratteri". Se il trailing ":" non è desiderato allora, sì, ciò che suggerisci farà, ovvero: $ $indice> 0 && $ 0.indice% 2 == 0? [":", $ 0.elemento]: [$ 0.elemento] ' – courteouselk

1

È il mio codice swift 4

let x = "11231245" 

var newText = String() 
    for (index, character) in x.enumerated() { 
     if index != 0 && index % 2 == 0 { 
      newText.append(":") 
     } 
     newText.append(String(character)) 
    } 
    print(newText) 

Uscite 11: 23: 12: 45

3

breve e semplice, aggiungere un let o due se si vuole

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 è il tasso

sepa mepl eas andt hank you

1

andrò per questa soluzione compatta (a Swift 4):

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

È possibile effettuare un'estensione e parametrizzare il passo e il separatore in modo che si può utilizzare per ogni valore che si desidera (In il mio caso, lo uso per scaricare a 32-bit di dati esadecimali spazio gestito):

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

Nel tuo caso questo dà i seguenti risultati:

let x = "11231245" 
print (x.separate(every:2, with: ":") 

$ 11:23:12:45 
Problemi correlati