Swift: xóa tất cả các phần tử mảng


108

Tôi đang cố gắng xóa tất cả các phần tử mảng bằng vòng lặp for như thế này:

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

Nhưng nó không hoạt động, tôi gặp lỗi này trước khi bulding:

Hy vọng ';' trong câu lệnh 'for'


5
Đơn giản. khởi tạo lại mảng ...
VJ

Câu trả lời:


326

Có một phương thức (thực ra là một hàm)

myArray.removeAll()

1
Tôi không biết về điều này, Cảm ơn +1
JamesG

11
@NoodleOfDeath Mảng Swift được nói một cách chính xác là structcác s và cấu trúc functionskhông giống như các lớp có methods.
vadian

1
@vadian +1 để làm rõ. Tôi quên Arrays là structs. Cựu chiến binh Objective-C coder đây ...
NoodleOfDeath

1
bạn có cần gọi hàm removeAll () khi thoát khỏi một khung nhìn (viewcontroller) nơi bạn khởi tạo nó không, hay nó tự biến mất !?
Famic Tech

1
@FamicTech Nó phụ thuộc: Nếu chế độ xem được dỡ bỏ, nó sẽ biến mất hoàn toàn, nếu chế độ xem chỉ biến mất, bạn phải gọi removeAll(). Tuy nhiên, thực hành tốt (kỷ luật bộ nhớ) là xóa tất cả dữ liệu không cần thiết khi một khung nhìn biến mất.
vadian

17

Dĩ nhiên rằng câu trả lời của @ vadian là giải pháp , tôi chỉ muốn chỉ ra rằng mã của bạn không hoạt động.

Trước hết, chỉ số mảng dựa trên 0, vì vậy bạn nên viết lại phạm vi cho phù hợp:

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

Tuy nhiên, việc triển khai này sẽ gây ra sự cố. Nếu bạn có một mảng 10 phần tử, phần tử cuối cùng chiếm vị trí ở chỉ số 9.

Sử dụng vòng lặp đó, ở lần lặp đầu tiên, phần tử ở chỉ mục 0 sẽ bị xóa và điều đó khiến phần tử cuối cùng chuyển xuống ở chỉ mục 8.

Ở lần lặp tiếp theo, phần tử ở chỉ mục 1 bị loại bỏ và phần tử cuối cùng chuyển xuống ở chỉ số 7. Và cứ tiếp tục như vậy.

Tại một số thời điểm trong vòng lặp, việc cố gắng xóa một phần tử cho một chỉ mục không tồn tại sẽ khiến ứng dụng gặp sự cố.

Khi xóa các phần tử khỏi một mảng trong một vòng lặp, cách tốt nhất để làm điều đó là duyệt nó theo thứ tự ngược lại:

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

Điều đó đảm bảo rằng các phần tử bị loại bỏ không thay đổi thứ tự hoặc chỉ số của các phần tử vẫn được xử lý.


1
Có một chức năng để loại bỏ tất cả các phần tử chỉ trong một dòng. như câu trả lời của @ vadian ...
VJ

3
@VJ đó là những gì tôi đã viết trong dòng đầu tiên của câu trả lời của mình :)
Antonio

+1 cho một giải pháp có thể được sử dụng để xóa một trường hợp cụ thể của một đối tượng. Tôi sử dụng 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 } }tốt nhất là không phải tất cả một dòng nhưng mã mà nên biên dịch trên cùng một dòng
NoodleOfDeath

Tại sao không for _ in 0...<myArray.count { myArray.removeAtIndex(0) }? Tôi chưa biết nhiều về hiệu quả, nhưng với cách này bạn không cần phải đảo ngược phạm vi, vì vậy có thể nó sẽ nhanh hơn.
cbjeukendrup

Điều đó cũng hoạt động! Phương pháp tương tự về hiệu quả, bạn loại bỏ từ đầu thay vì kết thúc, nhưng bạn lưu một biến :-)
Antonio

7

Bạn đang thiếu intừ khóa gây ra lỗi của bạn. Mã phải là:

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

Tuy nhiên, điều này sẽ không hoạt động như bạn mong đợi vì một số lý do:

  • Chỉ mục hợp lệ cuối cùng count - 1sẽ yêu cầu1..<myArray.count
  • Quan trọng hơn, việc xóa một phần tử khỏi một mảng sẽ rút ngắn nó, do đó thay đổi các chỉ mục mỗi lần.

Nếu bạn đang cố gắng xóa tất cả mọi thứ khỏi mảng thì bạn nên làm như những người khác đã đề xuất và sử dụng:

myArray.removeAll()

Trong trường hợp bạn chỉ muốn phần tử đầu tiên và không có gì khác, bạn có thể lấy tham chiếu đến đối tượng đầu tiên, hãy làm trống mảng, sau đó thêm đối tượng trở lại:

var firstElement = myArray.first!
myArray.removeAll()
myArray.append(firstElement)

Xin lỗi, tôi không thấy "trong" ... Đã +1
VJ

1
(+1) để giải thích lỗi thực tế. (-1) vì điều này sẽ không hoạt động, vì việc xóa một mục sẽ làm cho mảng ngắn hơn. (Cũng lưu ý rằng chỉ mục hợp lệ cuối cùngcount - 1).
Martin R

7

Nếu bạn thực sự muốn xóa mảng, cách đơn giản nhất là Khởi tạo lại mảng.


3

Mã của bạn sẽ hoạt động, nó không bị ràng buộc.

Swift 3

existingArray = []

Bằng cách này, bạn gán lại một mảng trống cho mảng hiện có và kiểu dữ liệu được tham chiếu.

Ngoài ra, bạn có thể sử dụng tính năng removeAllnày xóa tất cả các phần tử khỏi mảng và cung cấp tùy chọn để giữ dung lượng hiện có.

existingArray.removeAll()

Đây là một mutatinghàm có nghĩa là mảng gọi phương thức sẽ bị thay đổi (trống).


2

Kyle đang đi đúng hướng, nhưng mã của anh ta sẽ thất bại vì các chỉ số có thể giảm trong quá trình liệt kê, dẫn đến các chỉ số bất hợp pháp.

Một cách để giải quyết nó là liệt kê ngược. Nhanh chóng điều này được thực hiện bằng cách sử dụng các bước .

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

các tùy chọn khác sẽ được sử dụng filter()

Swift 1.2

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

Swift 2

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

Rất thú vị! Tôi không biết vềstride
Kyle Decot

1

Có phương thức removeAllObjects () có sẵn trong Swift 2

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

Để xóa phần tử tại chỉ mục cụ thể, hãy sử dụng:

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

Để loại bỏ việc sử dụng phần tử cuối cùng:

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

Để xóa các phần tử trong phạm vi cụ thể, hãy sử dụng:

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

Để loại bỏ việc sử dụng phần tử cụ thể:

Syntax : public func removeObject(anObject: AnyObject)

Ảnh chụp màn hình bên dưới hiển thị danh sách phương pháp có sẵn trong phần mở rộng NSMutableArray

Ảnh chụp màn hình 1


0

Bạn cũng có thể làm điều này:

for _ in myArray
{
    myArray.removeAtIndex(0)
}

2
Giải pháp này kém hiệu quả một cách khủng khiếp - trên mỗi lần lặp lại, tất cả các chỉ mục đối tượng tiếp theo đều bị dịch chuyển. Ngoài ra, tôi không chắc việc triển khai này có an toàn không. Ít nhất trong Objective-C tập hợp đột biến trong quá trình liệt kê bị cấm.
Borys Verebskyi

0

Để xóa tất cả dữ liệu khỏi một mảng

yourArrayData.removeAll()


0

Vadian có câu trả lời chính xác về những gì bạn đang cố gắng hoàn thành. Sự cố được hiển thị do mẫu mã của bạn là do cách bạn đang cố gắng tạo forvòng lặp. Indexsẽ bắt đầu từ 0 theo mặc định. Thêm vào một dải số sau nó không phải là cách chính xác để tạo vòng lặp for. Đó là lý do tại sao bạn gặp lỗi. Thay vào đó, hãy tạo vòng lặp for của bạn như sau:

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

Hy vọng rằng câu trả lời này sẽ giúp ích cho những người mới làm quen với Swift hoặc lập trình.


bạn nên sử dụng thuộc tính chỉ số mảng khi lặp lại bộ sưu tập. Không phải tất cả các bộ sưu tập đều bắt đầu từ chỉ mục 0
Leo Dabus

0

Để xóa tất cả các phần tử của mảng

var array = [1,2,3,4,5,6]()
array.removeAll()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.