Подтвердить что ты не робот

Как написать цикл for в Swift 3 для массива, который я изменяю во время цикла for?

Итак, у меня есть цикл for, который выглядит примерно так:

for var i = 0; i < results.count ; i += 1 {
   if (results[i] < 5) {
      results.removeAtIndex(i)
      i -= 1
   }
}

Это работало. Но когда я изменил его на предпочтительный синтаксис Swift 3.0:

for var i in 0..<results.count {
   if (results[i] < 5) {
      results.removeAtIndex(i)
      i -= 1
   }
}

Я получаю исключение массива IOOBE, потому что оно не проверяет счетчик и продолжается до исходного results.count.

Как это исправить? Он работает сейчас, но я не хочу вдаваться в неприятности в будущем.

4b9b3361

Ответ 1

В то время как решение, использующее filter, является прекрасным решением, и оно более быстрое, существует другой способ, если использовать for-in, тем не менее, все же желательно:

var results = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for var i in (0..<results.count).reverse()
{
    if (results[i] < 5)
    {
        results.removeAtIndex(i)
        //i -= 1
    }
}

print(results)

Результат:

[5, 6, 7, 8, 9, 10]

Мы могли бы вообще пропустить эту строку i -= 1, кроме того.

Проблема с removeAtIndex в цикле заключается в том, что он не заставит массив повторно индексировать себя на месте и, таким образом, исключить исключение из диапазона из-за того, что count не обновляется.

При обратном перемещении исключается исключение из-за пределов.

Ответ 2

Вместо этого вы можете использовать filter?

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let greaterThan5 = numbers.filter{$0 >= 5}
print(greaterThan5)

Ответ 3

Если вы хотите продолжить использование for -loop, вы можете перечислить как индекс, так и элемент с помощью enumerate:

for (index, element) in results.enumerate() {
   if (element < 5) {
     results.removeAtIndex(index)
   }
}

Хотя в зависимости от того, что вы делаете в своем цикле, метод filter может быть лучше.

Ответ 4

Если ваш цикл идет вперед...

for var i in (0..<results.count) where results.indices.contains(i) { 

//if the index doesn't exist, the loop will be stopped.

if (results[i] < 5) {
        results.removeAtIndex(i) 
    }

}