Assigning the contents of one Variable to another after split function producing an error

The three lines of code (//) that attempt to pass the contents from one variable to another crashes the app.

I added the (as! String) as suggested by the compiler because this error appeared instantly “ Cannot assign value of type 'Any' to type 'String' Insert " as! String" ”

I am still very new to Coding so this has me really stumped. Can someone shine some light on this please!

func extractFirstCardWordLetters () {

        let str = "happy.new.year.to.one.and.all"

        let ch = Character(".")

        cards.firstCardLettersResult = str.split(separator: ch)

        //cards.firstCardFirstLetters = cards.firstCardLettersResult [0] as! String

        //cards.firstCardSecondLetters = cards.firstCardLettersResult [1] as! String

        //cards.firstCardThirdLetters = cards.firstCardLettersResult [2] as! String

        print(cards.firstCardLettersResult) // prints ["happy", "new", "year", "to", "one", "and", "all"]

        print(cards.firstCardLettersResult[0]) // prints happy

        print(cards.firstCardLettersResult[1]) // prints new

        print(cards.firstCardLettersResult[2]) // prints year

    }

Answered by Claude31 in 740947022

You don't show enough code to fully understand what happens.

What is the crash message ? Probably trying to unwrap nil ?

Show the complete code, please.

I created a Cards struct to check

struct Cards {
    var firstCardLettersResult = [String]()
    var firstCardFirstLetters = ""
    var firstCardSecondLetters = ""
    var firstCardThirdLetters = ""
}
var cards = Cards()

func extractFirstCardWordLetters() {
    let str = "happy.new.year.to.one.and.all"
    let ch = Character(".")
    cards.firstCardLettersResult = str.split(separator: ch).map { String($0) }
    cards.firstCardFirstLetters = cards.firstCardLettersResult [0]
    cards.firstCardSecondLetters = cards.firstCardLettersResult [1]
    cards.firstCardThirdLetters = cards.firstCardLettersResult [2]
    print(cards.firstCardLettersResult) // prints ["happy", "new", "year", "to", "one", "and", "all"]
    print(cards.firstCardLettersResult[0]) // prints happy
    print(cards.firstCardLettersResult[1]) // prints new
    print(cards.firstCardLettersResult[2]) // prints year
}

extractFirstCardWordLetters()

I get the following log:

["happy", "new", "year", "to", "one", "and", "all"]
happy
new
year

Problem comes from here:

    cards.firstCardLettersResult = str.split(separator: ch)

You have probably defined cards.firstCardLettersResult as [String]

But split returns [subString]. So you need to convert each to String. That's what the map does:

    cards.firstCardLettersResult = str.split(separator: ch).map { String($0) }

If you are not familiar with map, it takes each item in the array, applies the change and puts in the new array. In a more easy to read form:

    cards.firstCardLettersResult = str.split(separator: ch).map { subString in return String(subString) }

Note: print(cards.firstCardLettersResult) works, because it does make the conversion internally.

Accepted Answer

You don't show enough code to fully understand what happens.

What is the crash message ? Probably trying to unwrap nil ?

Show the complete code, please.

I created a Cards struct to check

struct Cards {
    var firstCardLettersResult = [String]()
    var firstCardFirstLetters = ""
    var firstCardSecondLetters = ""
    var firstCardThirdLetters = ""
}
var cards = Cards()

func extractFirstCardWordLetters() {
    let str = "happy.new.year.to.one.and.all"
    let ch = Character(".")
    cards.firstCardLettersResult = str.split(separator: ch).map { String($0) }
    cards.firstCardFirstLetters = cards.firstCardLettersResult [0]
    cards.firstCardSecondLetters = cards.firstCardLettersResult [1]
    cards.firstCardThirdLetters = cards.firstCardLettersResult [2]
    print(cards.firstCardLettersResult) // prints ["happy", "new", "year", "to", "one", "and", "all"]
    print(cards.firstCardLettersResult[0]) // prints happy
    print(cards.firstCardLettersResult[1]) // prints new
    print(cards.firstCardLettersResult[2]) // prints year
}

extractFirstCardWordLetters()

I get the following log:

["happy", "new", "year", "to", "one", "and", "all"]
happy
new
year

Problem comes from here:

    cards.firstCardLettersResult = str.split(separator: ch)

You have probably defined cards.firstCardLettersResult as [String]

But split returns [subString]. So you need to convert each to String. That's what the map does:

    cards.firstCardLettersResult = str.split(separator: ch).map { String($0) }

If you are not familiar with map, it takes each item in the array, applies the change and puts in the new array. In a more easy to read form:

    cards.firstCardLettersResult = str.split(separator: ch).map { subString in return String(subString) }

Note: print(cards.firstCardLettersResult) works, because it does make the conversion internally.

Hello and thanks again for taking the time to help me. Unfortunately it will be some time before I am in a position to get back to this but wanted to reply without too much delay. Yes you are right about me being unfamiliar with .map so I will study it. I think without actually fully understanding the problem I suspected the issue was some kind of incompatibility that you are talking about. I thought by declaring var firstCardLetters = [String] () (which I did do) was enough to make it compatible with cards.firstCardLetters etc. Going from memory (mine) the Playgrounds Compiler suggested as! String which worked (immediate error gone) until I ran the app and then the app crashed with a what it called an “Unknown Error”. Until next year... Thanks again and a Happy New Year to you and Yours!

let str = cards.firstCardFirstWordClue

        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()

The above works okay with errors. As you suggested I inserted .map. I still needed the as! String after each split.

Not sure if .map { subString in return String(subString) } is an alternative form of as! String but it works without it.

Thanks again for your help!

EDIT: The above works okay WITHOUT errors.

Thanks again for your help.

The code I showed works without as! String. The 2 versions of .map are equivalent.

But may be you have defined struct Cards a bit differently ?

Assigning the contents of one Variable to another after split function producing an error
 
 
Q