Home > Back-end >  How to change the count of a for loop during the loop
How to change the count of a for loop during the loop

Time:11-18

I'm trying to change the number of items in array, over which a for loop is running, during the for loop, with the objective that this changes the number of loops. In a very simplified version, the code would look something like this:

var loopArray: [Int] = []

loopArray.append(1)
loopArray.append(2)
loopArray.append(3)
loopArray.append(4)
loopArray.append(5)

for x in 0..<Int(loopArray.count) {
    print(x)
    if x == 4 {
        loopArray.append(6)
    }
}

When running this code, 5 numbers are printed, and while the number 6 is added to the Array, the loopArray.count does not seem to update. How can I make the .count dynamic? This is a very simplified example, in the project I'm working on, appending numbers to the array depends on conditions that may or may not be met.

I have looked for examples online, but have not been able to find any similar cases. Any help or guidance is much appreciated.

CodePudding user response:

Joakim gives the correct way to do what you want, but I think there needs to be a bit of explanation as to why your solution doesn't work

The line

for x in 0..<Int(loopArray.count)

only evaluates loopArray.count once, the first time it is hit. This is because of the way for works. Conceptually a for loop iterates through the elements of a sequence. The syntax is something like

for x in s

where

  • s is a sequence, give it type S
  • x is a let constant (you can also make it a var but that is not relevant to the current discussion) with type S.Element

So the bit after the in is a sequence - any sequence. There's nothing special about the use of ..< here, it's just a convenient way to construct a sequence of consecutive integers. In fact, it constructs a Range (btw, you don't need the cast to Int, Array.count is already an Int).

The range is only constructed when you first hit the loop and it's effectively a constant because Range is a value type.

If you don't want to use Joakim's answer, you could create your own reference type (class) that conforms to Sequence and whose elements are Int and update the upper bound each time through the loop, but that seems like a lot of work to avoid a while loop.

CodePudding user response:

you can use a while loop instead of a for loop.

var i = 0
while i < loopArray.count {
    print(i)
    if i == 4 {
        loopArray.append(6)
    }
    
    i  = 1
}

which prints 0 1 2 3 4 5

  • Related