我知道你不应该,我知道为什么。但是我的意思是,一旦我真正想知道发生了什么,就不会理解自己的代码。
所以我有一个带有一堆对象的数组。我正在对其进行迭代,一旦找到具有特定类型的对象,便将其从数组中删除,然后将另一个对象添加到数组中。像这样:
var arr = parent.allchildren() //getting all the children in array
for ele in arr{
if(ele==somethingHere){
parent.remove(ele)
parent.add(new ele) //add new child into child array
}
}
如果我有一个1,2,3,4,5的数组,并且在迭代时删除了3并添加了6,则实际数组将是1,2,4,5,6,但我正在迭代的数组仍然是1,2,3,4,5。
我认为这会很好,因为最后我仍然可以得到想要的东西,它删除了元素并添加了我需要的元素。但是在迭代时修改列表很不好,您不应该这样做,但是就我而言,我认为它可以满足我的需求。我看不到的潜在问题是什么?
答案 0 :(得分:0)
我刚刚在操场上用以下代码进行了测试:
var arr = ["hi", "bye", "guy", "fry", "sky"]
for a in arr {
if arr.count >= 3 {
arr.remove(at: 2)
}
print(a)
}
print(arr)
此打印:
hi
bye
guy
fry
sky
["hi", "bye"]
因此,当您在Swift中使用for-in
循环时,似乎会复制该数组,并且您对其进行的更改将不会影响您要遍历的数组。要回答您的问题,只要您了解这是行为,那么这样做就没有错。
答案 1 :(得分:0)
您可能要考虑做的一件事是在迭代结束时进行所有更改。不必一一进行更改,而是在迭代时记录要进行的更改,然后在循环完成后实际进行更改。
例如,您可以创建要删除的元素数组,并添加要添加的元素数组。
//Our array where we record what we want to add
var elementsToAdd = [Any]()
//Our array of what elements we want to remove. We record the index at
//which we want to remove the element from the array
var indexesToRemoveAt = [Int]()
//Getting all the children in array
var arr = parent.allchildren()
//Enumerating an array allows us to access the index at which that
//element occurs. For example, the first element's index would be 0,
//the second element's index would be 1, the third would be 2, and so
//on
for (index,ele) in arr.enumerated() {
if(ele == somethingHere) {
indexesToRemoveAt.append(index)
elementsToAdd.append(newEle)
}
}
//Now that we have recorded the changes we want to make, we could make
//all of the changes at once
arr.remove(at: indexesToRemoveAt)
arr.append(contentsOf: elementsToAdd)
请注意,删除多个索引处的数组元素将需要对Array进行以下扩展。如果要避免创建此扩展名,则可以始终循环遍历索引数组,并告诉该数组在每个单独的索引处删除。这些扩展功能实际上所做的就是遍历索引,并删除该索引处的数组元素。
数组扩展以删除多个索引处的元素:
extension Array {
//Allows us to remove at multiple indexes instead of just one
mutating func remove(at indexes: [Int]) {
for index in indexes.sorted(by: >) {
if index <= count-1 {
remove(at: index)
}
}
}
}