在我的项目中,我有两个Ints阵列
在pseduocode中;
var existingOrders:[ExistingOrder] ...
var completedOrders:[CompletedOrder] ..
protocol ValueProtocol {
var value: Int { get set }
}
class ExistingOrder: ValueProtocol {
var value: Int = 0
}
class CompletedOrder: ValueProtocol {
var value: Int = 0
}
是的,我知道功能是一样的;但由于某个原因超出了这个问题的范围,我需要将它作为两个类。
我正在写的一个函数我需要将一个订单从现有订单转移到已完成。
在我的代码中,我循环遍历我要传输的所有值,然后传输它们
for (index, item) in self.completedOrders.enumerated() {
item.value = Die.roll()
self.transfer(index: index, destination: .existingOrder)
}
传递函数将其从existingOrder -> completedOrder
移开,反之亦然。
问题在于:
当它遍历上面显示的数组时,它会在传输过程中弹出一个对象;现在数组的大小已经改变,不再正确。
视觉上踩到它,看起来像这样;
即;
// stepping through the for-loop
existingOrders = [3,2]
transfer > index 0 (Integer value of 3) -> completed
existingOrders = [2]
transfer > index 1 .. crash; because the size of the array isn't correct any more.
因此for循环遍历它需要传输的每个项目,但由于传输本身正在修改for循环,它会更改所述数组的内容并导致崩溃。
我使用索引的原因是因为有时我希望传输现有订单中的特定项目。
我想知道如何避免这个问题?
由于
答案 0 :(得分:1)
以相反的顺序循环遍历数组。这样,早期的索引仍然有效,因为后面的项目被删除了:
for (index, item) in self.completedOrders.enumerated().reversed() {
item.value = Die.roll()
self.transfer(index: index, destination: .existingOrder)
}
以下是一个如何使用数字数组的示例,其中我们删除了几率:
var numbers = Array(1...10) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var odds = [Int]()
for (index, number) in numbers.enumerated().reversed() {
if number % 2 == 1 {
odds.insert(number, at: 0)
numbers.remove(at: index)
}
}
print(numbers) // [2, 4, 6, 8, 10]
print(odds) // [1, 3, 5, 7, 9]