4

I'm trying to change a tuple in an array , however ,when I try emo = (type:emo.type,strength:increaseStrength(emo.strength)) it gives me error

"cannot assign to 'let' value 'emo'

here is my code :

var emotions : [(type : String, strength: Int)] = [("happy",0),("scared",0),("tender",0),("excited",0),("sad",0)]

func increaseStrength(i:Int)->Int {
    switch i {
    case 0: return 1
    case 1: return 2
    case 2: return 3
    case 3: return 0
    default :return 0
    }
}

@IBAction func HappyBA(sender: AnyObject) {
    for emo in emotions  {
        if (emo.type == "happy" ){
            emo = (type:emo.type,strength:increaseStrength(emo.strength))

        }
    }
    println(emotions)
}

If there are better way to do the assignment please tell me I am so appreciated ! Thanks..

Yank
  • 718
  • 6
  • 17

1 Answers1

9

There is no point assigning to emo even if you could do it. This is not the same as replacing the corresponding object in the array - which is what you do want to do. emo is a copy; even if you were to set a property of it, it wouldn't affect the one back in the array. And certainly setting the variable would not magically read back into the array!

Here's one solution. Instead of cycling thru emotions in your for-loop, cycle thru enumerate(emotions). Now you have a tuple of an index number along with an emotion. If this is the right emotion type, write into the array via the index number.

for (ix,emo) in enumerate(emotions) {
    if emo.type == "happy" {
        emotions[ix] = (type:emo.type,strength:increaseStrength(emo.strength))
    }
}

Or you could use map.

emotions = emotions.map  {
    emo in
    if emo.type == "happy" {
        return (type:emo.type,strength:increaseStrength(emo.strength))
    } else {
        return emo
    }
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Hi Matt ,Thanks for your detailed answer and teaching me how to use map, my best wishes! – Yank Jan 13 '15 at 17:13
  • Btw @matt, I am glad I've viewed your book previously ,you are an awesome writer , will buy your newest book once you released . – Yank Jan 13 '15 at 17:19
  • @Yank Glad to help! Personally I like `map` better. In this case it's more lines of code, but it describes so clearly what you are going to do to your array. – matt Jan 13 '15 at 17:25
  • it's my pleasure to have your answer, I like map as well, I did computing science grade in uni , map is more reasonable and make the code looks more professional XD – Yank Jan 13 '15 at 17:40
  • `emo` is a copy because it's a tuple, correct? If it were an object, editing `emo` inside the loop would work? – Crashalot Feb 23 '16 at 19:12
  • @Crashalot Might help you to read this: http://stackoverflow.com/a/27366050/341994 – matt Feb 23 '16 at 19:51
  • @matt Thanks, very helpful! Do you happen to know this answer on property observers: http://stackoverflow.com/questions/35586564/swift-use-property-observers-while-defining-variables-one-per-line. Thanks again. – Crashalot Feb 23 '16 at 19:59
  • @Crashalot I don't know what a "property observer" is. Do you mean setter observer? – matt Feb 23 '16 at 20:04
  • Sorry, didn't realize it was a standard term, meant this: http://www.codingexplorer.com/swift-property-observers/ – Crashalot Feb 23 '16 at 20:11