Reputation: 3541
I have a for loop that loops over each element in an array. Under a certain condition, I add another element to that array inside the loop. However, the loop doesn't take that new element into account. If there are 6 items originally in the array and while looping through, I add 2 more, it still only loops 6 times. How can I fix this?
for ingredient in ingredientList {
if ingredient.name == "banana" {
var orange = Ingredient(name: "orange")
ingredientList.append(orange)
}
if ingredient.name == "orange" {
// this never executes
}
}
If one of my ingredients is a banana, add an orange to the list. However, the loop never even considers the newly added element. How can I accomplish something like this and why doesn't it work?
Upvotes: 6
Views: 14503
Reputation:
@ghostatron A collection’s indices property can hold a strong reference to the collection itself, causing the collection to be non-uniquely referenced. If you mutate the collection while iterating over its indices, a strong reference can cause an unexpected copy of the collection. To avoid the unexpected copy, use the index(after:) method starting with startIndex to produce indices instead.
var c = MyFancyCollection([10, 20, 30, 40, 50])
var i = c.startIndex
while i != c.endIndex {
c[i] /= 5
i = c.index(after: i)
}
// c == MyFancyCollection([2, 4, 6, 8, 10])
Upvotes: 1
Reputation: 848
You need to use a for loop instead of a for each loop and adjust the counter accordingly when adding an element
Int cntVar = 0
for x as Integer = 0 to ingredientList.count - 1 {
if ingredientList(x + cntVar).name == "banana" {
var orange = Ingredient(name: "orange")
ingredientList.append(orange)
x = x - 1
cntVar = cntVar + 1
}
if ingredientList(x + cntVar).name == "orange" {
//add needed function here
}
}
Upvotes: 0
Reputation: 2650
I think there are two issues here:
Generally speaking, you shouldn't modify a collection while enumerating it. At best, it will ignore you. In most languages it will just crash.
I suspect what you are seeing here, is that your loop is working with a copy of the collection, but your "append" is modifying the original. My reasoning there is that in Swift, structs are typically copies rather than references, and freakishly enough...arrays and dictionaries are structs.
Upvotes: 0
Reputation: 3438
try this:
var array = ["a", "b"]
for i in array.startIndex...array.endIndex {
if array[i] == "b" {
array.append("c")
print("add c")
}
if array[i] == "c"{
array.append("d")
print("add d")
}
}
Upvotes: 3