Search code examples
for-loopdictionarywhile-loopswift2enumerate

How to reset values in for loop in swift 2


I'm having trouble with the following line of code:

var participants = [String]()
var dict = [String: String]()

func createDictionary() {

    var hat = participants
    var loopCount = 0

    for (keyIndex, key) in hat.enumerate() {

        var valueIndex: Int {
            var index: Int
            repeat {
                index = Int(arc4random_uniform(UInt32(hat.count)))
                loopCount++
                print(loopCount)
                if loopCount > participants.count + 1000 {
                    createDictionary()
                }
            } while index == keyIndex || dict.values.contains(hat[index])
            return index
        }
        dict[key] = hat[valueIndex]
    }

}

My goal is for "dict" to contain a dictionary created from "participants". This function will work most of the time, but will sometimes enter into an infinite loop. I was trying to make it so that if it loops more than 1000 times or so, that the function would repeat and try again.

I think the problem is that I can't reset the values for "keyIndex" and "key" because those are "let constants". But I'm not sure.

Is there a way to reset the loop so those values? Or have the entire function retry?


Solution

  • So if anyone is interested, I was able to figure it out. I'm still new to this, so I'm sure others would have been able to figure it out quicker :)

    Anyway, I updated the code as follows:

    var participants = [String]()
    var dict = [String: String]()
    
    func createDictionary() {
    
        var hat = participants
        var drawName = [String: String]()
        var loopCount = 0
    
    
        for (keyIndex, key) in hat.enumerate() {
    
            var valueIndex: Int {
                var index: Int
                repeat {
                    loopCount++
                    index = Int(arc4random_uniform(UInt32(hat.count)))
                } while index == keyIndex || drawName.values.contains(hat[index]) && loopCount < hat.count + 50
    
                return index
            }
    
            drawName[key] = hat[valueIndex]
    
        }
    
        if loopCount > hat.count + 30 {
            self.createDictionary()
        } else {
            dict = drawName
        }
    
    }
    

    mathielo was right that I was most likely looking at this the wrong way. Basically I just instructed the loop to not loop too many times, then recalled the function if it had to try too many times to get a value. The above code works without freezing the program.