2015-10-23 7 views
6

Wie kann ich die angegebenen String in Swift in Gruppen mit gegebener Länge, von rechts nach links lesen?Split String in Gruppen mit bestimmter Länge

Zum Beispiel, ich habe String 123456789 und Gruppenlänge von 3. Die die Zeichenfolge sollten in drei Gruppen unterteilt werden: 123, 456, 789. String 1234567 wird in 1 unterteilt werden, 234, 567

So können Sie ein paar netten Code in Swift schreiben:

func splitedString(string: String, length: Int) -> [String] { 

} 

BTW versuchte Funktion split(), aber ich verstehe es funktioniert nur mit etwas Symbol zu finden

+0

Was das Ziel ist und was sind die Einschränkungen? Versuchen Sie Zahlenrepräsentationen zu formatieren, zB: "10000" wird zufällig zu "10 000"? – Moritz

+0

@EricD. Nein, NSNumberFormatter ist nicht mein Fall. Ich will nur wissen, kann ich diese Funktionalität mit 'split()' Funktion oder eine andere nette Lösung realisieren. – katleta3000

+0

Beachten Sie genau das gleiche (weil der * letzte * Chunk gekürzt wird, nicht der erste wie in Ihrem Beispiel), sondern Server als Ausgangspunkt: stackoverflow.com/a/28560013/1187415. –

Antwort

2

Nur meinen Beitrag zu diesem sehr voll Wettbewerb (SwiftStub) hinzuzufügen:

func splitedString(string: String, length: Int) -> [String] { 
    var result = [String]() 

    for var i = 0; i < string.characters.count; i += length { 
     let endIndex = string.endIndex.advancedBy(-i) 
     let startIndex = endIndex.advancedBy(-length, limit: string.startIndex) 
     result.append(string[startIndex..<endIndex]) 
    } 

    return result.reverse() 
} 

Oder wenn Sie Funktions-y fühlen:

func splitedString2(string: String, length: Int) -> [String] { 
    return 0.stride(to: string.characters.count, by: length) 
     .reverse() 
     .map { 
      i -> String in 
      let endIndex = string.endIndex.advancedBy(-i) 
      let startIndex = endIndex.advancedBy(-length, limit: string.startIndex) 
      return string[startIndex..<endIndex] 
     } 
} 
+0

@danke, mag deine Variante) – katleta3000

1

Das ist, was ich aus meinem Kopf kam. Ich wette, es gibt einen besseren Weg, es zu tun, also würde ich dich ermutigen, es weiter zu versuchen.

func splitedString(string: String, length: Int) -> [String] { 
    var groups = [String]() 
    var currentGroup = "" 
    for index in string.startIndex..<string.endIndex { 
     currentGroup.append(string[index]) 
     if currentGroup.characters.count == 3 { 
      groups.append(currentGroup) 
      currentGroup = "" 
     } 
    } 

    if currentGroup.characters.count > 0 { 
     groups.append(currentGroup) 
    } 

    return groups 
} 

waren hier meine Tests

let firstString = "123456789" 
let groups = splitedString(firstString, length: 3) 
// Returned ["123", "456", "789"] 

let secondString = "1234567" 
let moreGroups = splitedString(secondString, length: 3) 
// Returned ["123", "456", "7"] 
+0

Dies schneidet den letzten Chunk ab, nicht den ersten wie im Beispiel in der Frage. –

+0

Danke, ist es möglich, 'split()' Funktion zu verwenden? – katleta3000

+0

Ich habe versucht, das zu verwenden, aber derzeit ohne Glück. – aahrens

0

ich so etwas wie dies gemacht, konnte nichts besser schaffen suchen, aber das Ergebnis stimmt mit der Frage:

func splitedString(string: String, lenght: Int) -> [String] { 
    var result = [String](), count = 0, line = "" 
    for c in string.characters.reverse() { 
     count++; line.append(c) 
     if count == lenght {count = 0; result.append(String(line.characters.reverse())); line = ""} 
    } 
    if !line.isEmpty {result.append(String(line.characters.reverse()))} 
    return result.reverse() 
} 
1

Hier ist eine Version mit NSRegularExpressions

func splitedString(string: String, length: Int) -> [String] { 
    var groups = [String]() 
    let regexString = "(\\d{1,\(length)})" 
    do { 
     let regex = try NSRegularExpression(pattern: regexString, options: .CaseInsensitive) 
     let matches = regex.matchesInString(string, options: .ReportCompletion, range: NSMakeRange(0, string.characters.count)) 
     let nsstring = string as NSString 
     matches.forEach { 
      let group = nsstring.substringWithRange($0.range) as String 
      groups.append(group) 
     } 
    } catch let error as NSError { 
     print("Bad Regex Format = \(error)") 
    } 

    return groups 
} 
1

Hier ist eine weitere Version mit Functional Programming.

extension String{ 
    func splitedString(length: Int) -> [String]{ 
     guard length > 0 else { return [] } 
     let range = 0..<((characters.count+length-1)/length) 
     let indices = range.map{ length*$0..<min(length*($0+1),characters.count) } 
     return indices 
       .map{ characters.reverse()[$0.startIndex..<$0.endIndex] } 
       .map(String.init) 
    } 
} 

"1234567890".splitedString(3) 
0

Es gibt wahrscheinlich eine elegantere Lösung, aber das funktioniert:

func splitedString(string: String, length: Int) -> [String] { 
    let string = Array(string.characters) 
    let firstGroupLength = string.count % length 
    var result: [String] = [] 
    var group = "" 

    if firstGroupLength > 0 { 
     for i in 0..<firstGroupLength { 
      group.append(string[i]) 
     } 
     result.append(String(group)) 
     group = "" 
    } 

    for i in firstGroupLength..<string.count { 
     group.append(string[i]) 
     if group.characters.count == length { 
      result.append(group) 
      group = "" 
     } 
    } 
    return result 
} 

splitedString("abcdefg", length: 2) // ["a", "bc", "de", "fg"] 
splitedString("1234567", length: 3) // ["1", "234", "567"] 
0

Eine andere Lösung mit Substrings:

func splitStringByIntervals(str: String, interval: Int) -> [String] { 

    let st = String(str.characters.reverse()) 
    let length = st.characters.count 
    var groups = [String]() 

    for (var i = 0; i < length; i += interval) { 
     groups.append((st as NSString).substringWithRange(NSRange(location: i, length: min(interval, length - i)))) 
    } 

    return groups.map{ String($0.characters.reverse())}.reverse() 
} 

Der Ausgang für:

for element in splitStringByIntervals("1234567", interval: 3) { 
    print(element) 
} 

ist:

1 
234 
567 
1

Swift 4

Ich denke, die Erweiterungsmethode ist nützlicher.

extension String{ 

    public func splitedBy(length: Int) -> [String] { 

     var result = [String]() 

     for i in stride(from: 0, to: self.characters.count, by: length) { 
      let endIndex = self.index(self.endIndex, offsetBy: -i) 
      let startIndex = self.index(endIndex, offsetBy: -length, limitedBy: self.startIndex) ?? self.startIndex 
      result.append(String(self[startIndex..<endIndex])) 
     } 

     return result.reversed() 

    } 

} 

das Anwendungsbeispiel:

Swift.debugPrint("123456789".splitedBy(length: 4)) 
// Returned ["1", "2345", "6789"]