Search code examples
arraysswiftloopswhile-loopiteration

How to better use repeat while loop for indexing and array


I want to randomly pick a KanjiCard struct item from a given array, add the property "kanji" to another temp array and perform a check, if the randomly picked struct.kanji is present in the yetShowedArray repeat the random pick until you find a struct which kanji is not present in yetShowedArray in order to use it

the actual repeat/while flow does not assure it happens.

//test for the not repeating run *************************************************************************************
        
        //check if the two array have the same number of items
        guard arrayToUse.count !=  yetShowedArray.count else {
            print("finished all the kanji")
            var matching = 0
            for element in arrayToUse {
                if yetShowedArray.contains(element.kanji!){
                    matching += 1
                }
            }
            print("matching kanji are : \(matching)")
            return
        }
        
        var random = Int(arc4random_uniform(UInt32(arrayToUse.count)))

        //Instance
        kanjiToShow = arrayToUse[random]
        guard let kanjiToTrack = kanjiToShow.kanji else {
            print("kanjiToTrack is nil!!!")
            return
        }
        
        
        if yetShowedArray.contains(kanjiToTrack){
            print("contained")

            repeat {
                random = Int(arc4random_uniform(UInt32(arrayToUse.count)))
                kanjiToShow = arrayToUse[random]

            } while yetShowedArray.contains(kanjiToTrack)
            print("refreshed random")

        }
        else {
            print("never used before")
        }
        
        yetShowedArray.append(kanjiToTrack)
        print(yetShowedArray)

        print("arrayToUse: \(arrayToUse.count) yetShowedArray: \(yetShowedArray.count)")
        
        //test for the not repeating run *************************************************************************************

SOLUTION

found after Anton Novoselov's answer

I changed the let kanjiToTrack to a var then refreshed it inside the repeat loop

//Instance
        kanjiToShow = arrayToUse[random]
        guard var kanjiToTrack = kanjiToShow.kanji else {
            print("kanjiToTrack is nil!!!")
            return
        }
        
        
        if yetShowedArray.contains(kanjiToTrack){
            print("contained")

            repeat {
                random = Int(arc4random_uniform(UInt32(arrayToUse.count)))
                kanjiToShow = arrayToUse[random]
                kanjiToTrack = kanjiToShow.kanji!
                
                
            } while yetShowedArray.contains(kanjiToTrack)
            
            print("refreshed random")

        }
        else {
            print("never used before")
        }

second solution

let random = Int(arc4random_uniform(UInt32(arrayToUse.count)))

    //Instance
    kanjiToShow = arrayToUse[random]
    guard kanjiToShow.kanji != nil else {
        print("kanjiToTrack is nil!!!")
        return
    }
    
    arrayToUse.remove(at: random)

Solution

  • Try to refresh kanjiToTrack again inside repeat loop. As you said, it's struct - value type, so it seems you checking the same kanjiToTrack in while clause. Try this:

           repeat {
                random = Int(arc4random_uniform(UInt32(arrayToUse.count)))
                kanjiToShow = arrayToUse[random]
                guard let kanjiToTrack = kanjiToShow.kanji else {return}
    
    
            } while yetShowedArray.contains(kanjiToTrack)