Удаление из массива во время перечисления в Swift?

Я хочу перечислить массив в Swift и удалить определенные элементы. Мне интересно, безопасно ли это делать, а если нет, то как я должен это достичь.

В настоящее время я бы это сделал:

for (index, aString: String) in enumerate(array) { //Some of the strings... array.removeAtIndex(index) } 

  • iOS / Mac OS: сохранение и сравнение CGPoints / NSPoints в массивах
  • NSMutableArray enumerateObjectsUsingBlock не является синхронным, как говорит Apple
  • получение «NSOrderedSetArrayProxy было мутировано при перечислении» ошибка без мутации
  • Swift Добавляет каждый второй элемент в массив
  • Прокрутите через subview, чтобы проверить наличие пустого UITextField - Swift
  • Перечислите NSArray, начиная с индекса givven, ищите оба пути (без обтекания)
  • Внедрение NSFastEnumerator: EXC_BAD_ACCESS при повторном выполнении для ... в
  • Не понимаю причину ошибки компиляции «Ожидаемый тип» в объявлении метода, когда тип определен
  • 7 Solutions collect form web for “Удаление из массива во время перечисления в Swift?”

    В Swift 2 это довольно просто, используя enumerate и reverse .

     var a = [1,2,3,4,5,6] for (i,num) in a.enumerate().reverse() { a.removeAtIndex(i) } print(a) 

    Смотрите мой быстрый сценарий здесь: http://swiftstub.com/944024718/?v=beta

    Вы можете рассмотреть способ filter :

     var theStrings = ["foo", "bar", "zxy"] // Filter only strings that begins with "b" theStrings = theStrings.filter { $0.hasPrefix("b") } 

    Параметр filter – это просто замыкание, которое принимает экземпляр типа массива (в данном случае String ) и возвращает Bool . Когда результат true он сохраняет элемент, иначе элемент отфильтровывается.

    Когда элемент с определенным индексом удаляется из массива, все последующие элементы будут изменять свою позицию (и индекс), поскольку они сдвигаются назад на одну позицию.

    Таким образом, наилучшим способом является перемещение массива в обратном порядке – и в этом случае я предлагаю использовать традиционный цикл for:

     for var index = array.count - 1; index >= 0; --index { if condition { array.removeAtIndex(index) } } 

    Однако, на мой взгляд, лучший подход заключается в использовании метода filter , как описано в его ответе @perlfly.

    В Swift 3 это будет:

    С цифрами, согласно ответу Джонстона:

     var a = [1,2,3,4,5,6] for (i,num) in a.enumerated().reversed() { a.remove(at: i) } print(a) 

    С строками как вопрос OP:

     var b = ["a", "b", "c", "d", "e", "f"] for (i,str) in b.enumerated().reversed() { if str == "c" { b.remove(at: i) } } print(b) 

    Нет, это небезопасно, чтобы мутировать массивы во время перезаписи, ваш код сработает.

    Если вы хотите удалить только несколько объектов, вы можете использовать функцию filter .

    Либо создайте изменчивый массив для хранения элементов, которые нужно удалить, а затем, после перечисления, удалите эти элементы из оригинала. Или создайте копию массива (неизменяемый), перечислите это и удалите объекты (не по индексу) из оригинала при перечислении.

    Я рекомендую установить элементы в nil во время перечисления, а после завершения удалить все пустые элементы с помощью метода array ().

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.