Swift: удалить все элементы массива

108

Я пытаюсь удалить все элементы массива с помощью цикла for следующим образом:

for index 1...myArray.count {
   myArray.removeAtIndex(index)
}

Но это не работает, я получаю эту ошибку перед сборкой:

Ожидается ';' в заявлении "для"

Мехмет
источник
5
Просто. повторно инициализировать массив ...
VJ

Ответы:

326

Есть метод (фактически функция)

myArray.removeAll()
вадиан
источник
1
Не знал об этом, спасибо +1
JamesG
12
@NoodleOfDeath Строго говоря, массивы Swift - это structs, а в структурах есть functionsклассы, которые не имеют methods.
vadian
1
@vadian +1 за разъяснения. Я забыл Arrays are structs. Ветеран Objective-C здесь ...
NoodleOfDeath
1
вам нужно вызывать функцию removeAll () при выходе из представления (viewcontroller), в котором вы его инициализировали, или он уходит сам по себе !?
Famic Tech
1
@FamicTech Это зависит: если представление выгружено, оно неявно исчезает, если представление только исчезает, вам нужно вызвать removeAll(). Однако хорошая практика (дисциплина памяти) - удалять все ненужные данные, когда представление исчезает.
vadian
17

Принимая как должное, что ответ @vadian - это решение , я просто хочу отметить, что ваш код не работает.

Прежде всего, индексы массива начинаются с 0, поэтому вам следует соответственно переписать диапазон:

for index 0..<myArray.count {
   myArray.removeAtIndex(index)
}

Однако эта реализация приведет к сбою. Если у вас есть массив из 10 элементов, последний элемент занимает позицию с индексом 9.

Используя этот цикл, на первой итерации удаляется элемент с индексом 0, что приводит к смещению последнего элемента по индексу 8.

На следующей итерации элемент с индексом 1 удаляется, а последний элемент смещается вниз по индексу 7. И так далее.

В какой-то момент цикла попытка удалить элемент для несуществующего индекса приведет к сбою приложения.

При удалении элементов из массива в цикле лучший способ сделать это - пройти по нему в обратном порядке:

for index in reverse(0..<myArray.count) {
    myArray.removeAtIndex(index)
}

Это гарантирует, что удаленные элементы не изменят порядок или индекс элементов, которые еще предстоит обработать.

Антонио
источник
1
Есть функция для удаления всех элементов одной строкой. как ответ @ vadian ...
VJ
3
@VJ это то, что я написал в первой строке своего ответа :)
Антонио
+1 за решение, которое можно использовать для удаления определенного экземпляра объекта. Я public extension Array where Element : Equatable { public mutating func remove(element: Element) -> Int { var occurrences = 0; for index in (0 ..< count).reverse() { if self[index] == element { removeAtIndex(index); occurrences += 1 } }; return occurrences } }предпочтительно использую не всю одну строку, но этот код должен компилироваться в одну строку
NoodleOfDeath
А почему бы и нет for _ in 0...<myArray.count { myArray.removeAtIndex(0) }? Я пока не очень хорошо разбираюсь в эффективности, но в этом случае вам не нужно менять диапазон, так что, возможно, это быстрее.
cbjeukendrup
Это тоже работает! Тот же метод с точки зрения эффективности, вы удаляете с начала, а не с конца, но сохраняете переменную :-)
Антонио
7

Вам не хватает inключевого слова, которое вызывает ошибку. Код должен быть:

for index in 1...myArray.count {
    myArray.removeAtIndex(index)
}

Однако это не сработает так, как вы ожидали, по нескольким причинам:

  • Последний действительный индекс, count - 1который потребует1..<myArray.count
  • Что еще более важно, удаление элемента из массива укорачивает его, тем самым меняя индексы каждый раз.

Если вы пытаетесь удалить все элементы из массива, вам следует сделать, как предлагали другие, и использовать:

myArray.removeAll()

В случае, если вам нужен только первый элемент и ничего больше, вы можете получить ссылку на первый объект, очистите массив, а затем снова добавьте объект:

var firstElement = myArray.first!
myArray.removeAll()
myArray.append(firstElement)
Кайл Декот
источник
Извините, я не видел "в" ... Сделал +1
VJ
1
(+1) для объяснения фактической ошибки. (-1), потому что это не сработает, так как удаление элемента делает массив короче. (Обратите внимание также, что последний действительный индекс count - 1).
Martin R
7

Если вы действительно хотите очистить массив, самый простой способ - это повторно инициализировать его.

VJ
источник
3

Ваш код должен работать, он просто выходит за рамки.

Swift 3

existingArray = []

Делая это, вы повторно назначаете пустой массив существующему массиву и указываете тип данных.

В качестве альтернативы вы можете использовать, removeAllкоторый удаляет все элементы из массива и предоставляет возможность сохранить существующую емкость.

existingArray.removeAll()

Это mutatingфункция, которая означает, что массив, вызывающий метод, будет изменен (пуст).

Lorem
источник
2

Кайл находится на правильном пути, но его код выйдет из строя, так как возможные индексы уменьшатся во время перечисления, что приведет к незаконным индексам.

Один из способов решить эту проблему - перечислить в обратном порядке. В быстром темпе это делается шагами .

for index in stride(from: myArray.count - 1, through: 0, by: -1) {
    myArray.removeAtIndex(index)
}

другими вариантами было бы использовать filter()

Swift 1.2

myArray = filter(myArray, { (obj) -> Bool in
    return false
})

Swift 2

myArray = myArray.filter{ (obj) -> Bool in
    return false
}
викингосегундо
источник
Очень интересно! Я не знал оstride
Кайл Декот 02
1

В Swift 2 есть метод removeAllObjects ()

Syntax :  public func removeAllObjects()
Eg.:   mainArray.removeAllObjects

Чтобы удалить элемент по определенному индексу, используйте:

Syntax : public func removeObjectAtIndex(index: Int)
Eg.: mainArray.removeObjectAtIndex(5)

Чтобы удалить последний элемент, используйте:

Syntax : public func removeLastObject()
Eg.: mainArray.removeLastObject()

Чтобы удалить элементы в определенном диапазоне, используйте:

Syntax : public func removeObject(anObject: AnyObject, inRange range: NSRange)

Чтобы удалить определенный элемент, используйте:

Syntax : public func removeObject(anObject: AnyObject)

На скриншоте ниже показан список методов, доступных в расширении NSMutableArray.

Скриншот 1

Джайпракаш Дубей
источник
0

Вы также можете сделать это:

for _ in myArray
{
    myArray.removeAtIndex(0)
}
Дарт Флайтер
источник
2
Это решение ужасно неэффективно - на каждой итерации смещаются все последующие индексы объектов. Кроме того, я не уверен, что эта реализация безопасна. По крайней мере, в коллекциях Objective-C мутация во время перебора запрещена.
Борис Веребский
0

Для удаления всех данных из массива

yourArrayData.removeAll()

Ронак
источник
0

У Вадиана есть правильный ответ о том, чего вы пытаетесь достичь. Проблема, показанная в результате вашего образца кода, связана с тем, как вы пытаетесь создать forцикл. Indexпо умолчанию будет начинаться с 0. Добавление диапазона чисел после этого - неправильный способ создания цикла for. Вот почему вы видите ошибку. Вместо этого создайте цикл for следующим образом:

for index in myArray.indices {
    // Do stuff
}

Надеюсь, этот ответ поможет другим, кто плохо знаком с Swift или программированием.

Джош Грач
источник
при итерации коллекции следует использовать свойство index index. Не все коллекции начинаются с нулевого индекса
Лео Дабус
0

Для удаления всех элементов массива

var array = [1,2,3,4,5,6]()
array.removeAll()
Имран Рашид
источник