5

Target: A string with a built-in separator shall be split in an int and another string. In the case that the separator sequence '###' occurs more than once, the string shall always be spliced at the last '###'.

Is there an operator like string.lastIndexOf("###"), like in C#?

This is how my parser looks like:

func parseTuple(from string: String) -> (String, Int)? {
    let parsedString = string.components(separatedBy: "###")
    if let tupleString = String(parsedString[0]), let tupleInt = Int(parsedString[1]) {
        return (tupleString, tupleInt)
    } else {
        return nil
    }
}
shallowThought
  • 19,212
  • 9
  • 65
  • 112
procra
  • 535
  • 4
  • 29
  • Can you provide an example input and output? – Luca Angeletti Jul 03 '17 at 11:07
  • Connect###Four###Player###7 should be parsed to a string "Connect###Four###Player" and to an int 7. So no matter how many '###' there are, the function shall always split the last one and leave out the remaining. – procra Jul 03 '17 at 11:09

2 Answers2

7

The range(of:...) method of String has a .backwards option to find the last occurrence of a string. Then substring(to:) and substring(from:) can be used with the lower/upper bound of that range to extract the parts of the string preceding/following the separator:

func parseTuple(from string: String) -> (String, Int)? {

    if let theRange = string.range(of: "###", options: .backwards),
        let i = Int(string.substring(from: theRange.upperBound)) {
        return (string.substring(to: theRange.lowerBound), i)
    } else {
        return nil
    }
}

Example:

if let tuple = parseTuple(from: "Connect###Four###Player###7") {
    print(tuple)
    // ("Connect###Four###Player", 7)
}

Swift 4 update:

func parseTuple(from string: String) -> (String, Int)? {

    if let theRange = string.range(of: "###", options: .backwards),
        let i = Int(string[theRange.upperBound...]) {
        return (String(string[...theRange.lowerBound]), i)
    } else {
        return nil
    }
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
3
let input = "Connect###Four###Player###7"

let seperator = "###"
// split components
var components = input.components(separatedBy: seperator)
// remove the last component ...
components = Array(components.dropLast())
// ... and re-join the remaining ones
let output = components.joined(separator: seperator)

print(output)

prints:

Connect###Four###Player
shallowThought
  • 19,212
  • 9
  • 65
  • 112