Still requires an error trap to prevent an index out of range when eg. hello.world. (no word after the world full-stop, hello..today also produces the same error for example) is mistakenly entered in my firstCardWords field. I have managed to trap spaces, not having the required number of full-stops and a nil entry but nothing after a full-stop produces an error that crashes the app. Also is there a better way to handle this input (preferably not too complicated ) to prevent all instances that will cause index out of range in this example?
func makeFirstCardWordLetters () {
if cards.firstCardWords == "" {
cards.firstCardWords = "FIRST.CARD.WORD"
}
var numOccurrences = cards.firstCardWords.filter{ $0 == "." }.count
if numOccurrences != 2 {
cards.firstCardWords = "TWO.FULL-STOPS.PLEASE"
}
numOccurrences = cards.firstCardWords.filter{ $0 == " " }.count
if numOccurrences != 0 {
cards.firstCardWords = "NO.SPACES.PLEASE"
}
let str = cards.firstCardWords
let ch = Character(".")
cards.firstCardLettersResult = str.split(separator: ch).map { String($0) }
cards.firstCardFirstLetters = cards.firstCardLettersResult[0] as! String
cards.firstCardSecondLetters = cards.firstCardLettersResult[1] as! String
cards.firstCardThirdLetters = cards.firstCardLettersResult[2] as! String
makeSecondCardWordLetters()
}
I missed this case.
It is because of how split works.
If nothing before separtor, then no item is created.
For instance
"hello.you.boy" creates ["hello", "you", "boy"]
but
".you.boy" creates [ "you", "boy"] // only 2 items
and
".you." creates ["you"]
So you could make an initial test:
func makeFirstCardWordLetters () {
let test = firstCardWords.split(separator: ".").map { String($0) }
if test.count < 3 {
firstCardWords = "MUST-HAVE.WORDS.BETWEEN-FULL-STOPS"
return
}
To get the detailed diagnostic of what is missing:
extension String { // Credit https://stackoverflow.com/questions/40413218/swift-find-all-occurrences-of-a-substring
func indices(of string: String) -> [Int] {
return indices.reduce([]) { $1.encodedOffset > ($0.last ?? -1) && self[$1...].hasPrefix(string) ? $0 + [$1.encodedOffset] : $0 }
}
}
func makeFirstCardWordLetters () {
let positions = firstCardWords.indices(of: ".")
if positions.count < 2 {
firstCardWords = "MUST-HAVE.WORDS.BETWEEN-FULL-STOPS"
return
}
if positions[0] == 0 {
firstCardWords = "FIRST.WORD.MISSING"
return
}
if positions[1] == positions[0] + 1 {
firstCardWords = "SECOND.WORD.MISSING"
return
}
if positions[1] == firstCardWords.count - 1 {
firstCardWords = "THIRD.WORD.MISSING"
return
}
// more code