Swift: ลบองค์ประกอบอาร์เรย์ทั้งหมด


108

ฉันกำลังพยายามลบองค์ประกอบอาร์เรย์ทั้งหมดด้วย for loop ดังนี้:

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

แต่ไม่ได้ผลฉันได้รับข้อผิดพลาดนี้ก่อนทำการ bulding:

คาดว่า ';' ในคำสั่ง 'for'


5
เรียบง่าย เริ่มต้นอาร์เรย์ใหม่ ...
VJ

คำตอบ:


326

มีวิธีการ (จริง ๆ แล้วฟังก์ชั่น)

myArray.removeAll()

1
ไม่ทราบเกี่ยวกับเรื่องนี้ขอบคุณ +1
JamesG

12
@NoodleOfDeath อาร์เรย์ Swift ที่พูดอย่างเคร่งครัดคือstructs และโครงสร้างfunctionsไม่เหมือนคลาสที่มีmethodsไฟล์.
vadian

1
@vadian +1 สำหรับคำชี้แจง ฉันลืมArrays are structs Veteran Objective-C coder ที่นี่ ...
NoodleOfDeath

1
คุณจำเป็นต้องเรียกใช้ฟังก์ชัน removeAll () เมื่อออกจากมุมมอง (ตัวควบคุมมุมมอง) ที่คุณเริ่มต้นหรือไม่หรือมันจะหายไปเอง!
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
มีฟังก์ชั่นในการลบองค์ประกอบทั้งหมดในบรรทัดเดียว as @ vadian's answer ...
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

หากคุณต้องการล้างอาร์เรย์จริงๆวิธีที่ง่ายที่สุดคือการเริ่มต้นใหม่


3

รหัสของคุณควรใช้งานได้มันไม่ได้อยู่ในขอบเขต

สวิฟต์ 3

existingArray = []

โดยการทำเช่นนี้คุณจะกำหนดอาร์เรย์ว่างให้กับอาร์เรย์ที่มีอยู่อีกครั้งและชนิดข้อมูลจะถูกอ้างอิง

หรือคุณสามารถใช้removeAllซึ่งจะลบองค์ประกอบทั้งหมดออกจากอาร์เรย์และให้ตัวเลือกเพื่อรักษาความจุที่มีอยู่

existingArray.removeAll()

นี่คือmutatingฟังก์ชั่นซึ่งหมายความว่าอาร์เรย์ที่เรียกเมธอดจะถูกเปลี่ยน (ว่าง)


2

Kyle มาถูกทางแล้ว แต่รหัสของเขาจะล้มเหลวเนื่องจากดัชนีที่เป็นไปได้ลดลงระหว่างการแจกแจงทำให้ดัชนีผิดกฎหมาย

วิธีหนึ่งในการแก้ปัญหาคือการระบุย้อนกลับ ในที่รวดเร็วนี้จะกระทำโดยใช้ความก้าวหน้า

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
})

สวิฟต์ 2

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

น่าสนใจมาก! ฉันไม่รู้stride
Kyle Decot

1

มีวิธีremoveAllObjects () ที่มีอยู่ใน Swift 2

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 ระหว่างการแจงนับเป็นสิ่งต้องห้าม
Borys Verebskyi

0

สำหรับการลบข้อมูลทั้งหมดออกจากอาร์เรย์

yourArrayData.removeAll()


0

Vadian มีคำตอบที่ถูกต้องในแง่ของสิ่งที่คุณพยายามทำให้สำเร็จ ปัญหาที่แสดงเป็นผลมาจากตัวอย่างโค้ดของคุณเกิดจากวิธีที่คุณพยายามสร้างforลูป Indexจะเริ่มต้นที่ 0 โดยค่าเริ่มต้น การเพิ่มช่วงตัวเลขหลังจากไม่ใช่วิธีที่ถูกต้องในการสร้าง for loop นั่นเป็นเหตุผลที่คุณเห็นข้อผิดพลาด ให้สร้าง for loop ของคุณแทนดังนี้:

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

หวังว่าคำตอบนี้จะช่วยให้ผู้อื่นที่ยังใหม่กับ Swift หรือการเขียนโปรแกรม


คุณควรใช้คุณสมบัติดัชนีอาร์เรย์เมื่อทำซ้ำคอลเลกชัน คอลเลกชันทั้งหมดไม่ได้เริ่มต้นที่ดัชนีศูนย์
Leo Dabus

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.