3

I would like to split the string by two symbols in Swift. So after string "df57g5df7g" I would like to obtain an Array ["df","57","g5","df","7g"]. Is it possible to force iterator

for i in word.characters {
 print(i)
}

to jump by two symbols, and get acsess to the next symbol inside the loop?

  • 4
    See http://stackoverflow.com/questions/32212220/how-to-split-a-string-into-substrings-of-equal-length – Wiktor Stribiżew Aug 16 '16 at 16:12
  • 1
    Possible duplicate of [Swift: what is the right way to split up a \[String\] resulting in a \[\[String\]\] with a given subarray size?](http://stackoverflow.com/questions/26395766/swift-what-is-the-right-way-to-split-up-a-string-resulting-in-a-string-wi) – Michael Kohl Aug 16 '16 at 16:19
  • 2
    This looks like it might be a hex string and wonder if your intent is to build a `NSData` from that. If so, I'd bypass the array of two character hex strings, but rather stride through this string and build the `NSData` directly. – Rob Aug 16 '16 at 17:27

3 Answers3

5

A simple while loop:

let str = "df57g5df7g"

var startIndex = str.startIndex
var result = [String]()

repeat {
    let endIndex = startIndex.advancedBy(2, limit: str.endIndex)
    result.append(str[startIndex..<endIndex])

    startIndex = endIndex
} while startIndex < str.endIndex

print(result)

Or something more Swifty:

let result = 0.stride(to: str.characters.count, by: 2).map { i -> String in
    let startIndex = str.startIndex.advancedBy(i)
    let endIndex   = startIndex.advancedBy(2, limit: str.endIndex)
    return str[startIndex..<endIndex]
}
Code Different
  • 90,614
  • 16
  • 144
  • 163
1

This might not be the slickest solution, but it works:

var word = "df57g5df7g"

var pairsArray = [String]()

while word.characters.count > 1 {
    let firstCharacter = word.removeAtIndex(word.startIndex)
    let secondCharacter = word.removeAtIndex(word.startIndex)
    pairsArray.append("\(firstCharacter)\(secondCharacter)")
}

print(pairsArray)

The result is:

["df", "57", "g5", "df", "7g"]
Westside
  • 675
  • 1
  • 7
  • 16
1

This is the best solution I've seen, taken from the SwiftSequence library.

extension CollectionType {
    public func chunk(n: Index.Distance) -> [SubSequence] {
        var res: [SubSequence] = []
        var i = startIndex
        var j: Index
        while i != endIndex {
            j = i.advancedBy(n, limit: endIndex)
            res.append(self[i..<j])
            i = j
        }
        return res
    }
}

let word = "df57g5df7g"
let pairs = word.characters.chunk(2).map(String.init)
print(pairs) //["df", "57", "g5", "df", "7g"]

You can see it in action here.

Alexander
  • 59,041
  • 12
  • 98
  • 151