ฉันจะยกเลิกการตั้งค่า / ลบองค์ประกอบออกจากอาร์เรย์ใน Swift ภาษาใหม่ของ Apple ได้อย่างไร
นี่คือรหัสบางส่วน:
let animals = ["cats", "dogs", "chimps", "moose"]
องค์ประกอบanimals[2]
จะถูกลบออกจากอาร์เรย์ได้อย่างไร
ฉันจะยกเลิกการตั้งค่า / ลบองค์ประกอบออกจากอาร์เรย์ใน Swift ภาษาใหม่ของ Apple ได้อย่างไร
นี่คือรหัสบางส่วน:
let animals = ["cats", "dogs", "chimps", "moose"]
องค์ประกอบanimals[2]
จะถูกลบออกจากอาร์เรย์ได้อย่างไร
คำตอบ:
let
คำหลักเป็นค่าคงที่ประกาศว่าไม่สามารถเปลี่ยนแปลงได้ หากคุณต้องการแก้ไขตัวแปรคุณควรใช้var
แทนเช่น:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.remove(at: 2) //["cats", "dogs", "moose"]
ทางเลือกที่ไม่มีการกลายพันธุ์ที่จะทำให้คอลเลกชันดั้งเดิมไม่เปลี่ยนแปลงคือการใช้filter
เพื่อสร้างคอลเลกชันใหม่โดยไม่ต้องลบองค์ประกอบที่คุณต้องการเช่น:
let pets = animals.filter { $0 != "chimps" }
ป.ร. ให้ไว้
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeFirst() // "cats"
print(animals) // ["dogs", "chimps", "moose"]
animals.removeLast() // "moose"
print(animals) // ["cats", "dogs", "chimps"]
animals.remove(at: 2) // "chimps"
print(animals) // ["cats", "dogs", "moose"]
สำหรับองค์ประกอบเดียวเท่านั้น
if let index = animals.firstIndex(of: "chimps") {
animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]
สำหรับองค์ประกอบหลายรายการ
var animals = ["cats", "dogs", "chimps", "moose", "chimps"]
animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]
filter
) และกลับองค์ประกอบที่ถูกลบdropFirst
หรือdropLast
สร้างอาเรย์ใหม่ได้อัปเดตเป็น Swift 5.2
คำตอบข้างต้นดูเหมือนจะเข้าใจว่าคุณรู้ว่าดัชนีขององค์ประกอบที่คุณต้องการลบ
บ่อยครั้งที่คุณรู้จักการอ้างอิงไปยังวัตถุที่คุณต้องการลบในอาร์เรย์ (คุณวนซ้ำผ่านอาร์เรย์ของคุณและพบมันเช่น) ในกรณีเช่นนี้มันอาจจะทำงานได้ง่ายขึ้นกับการอ้างอิงวัตถุโดยตรงโดยไม่ต้องผ่านทุกดัชนีของมัน ดังนั้นฉันขอแนะนำวิธีนี้ มันใช้ตัวดำเนินการประจำตัว !==
ซึ่งคุณใช้เพื่อทดสอบว่าวัตถุสองอ้างอิงทั้งสองอ้างถึงอินสแตนซ์วัตถุเดียวกัน
func delete(element: String) {
list = list.filter() { $0 !== element }
}
แน่นอนว่านี่ไม่ได้ผลสำหรับString
s เท่านั้น
list = list.filter({ $0 != element })
array.indexOf({ $0 == obj })
list
การลบนี้จะไม่อัปเดตการอ้างอิงอาร์เรย์อื่น ๆ list
ตั้งแต่คุณกำหนดอาร์เรย์ใหม่เพื่อ เพียงแค่ความหมายที่ลึกซึ้งถ้าคุณลบจากอาร์เรย์ด้วยวิธีนี้
Swift 5: นี่คือส่วนขยายที่เย็นและง่ายต่อการลบองค์ประกอบในอาร์เรย์โดยไม่ต้องกรอง:
extension Array where Element: Equatable {
// Remove first collection element that is equal to the given `object`:
mutating func remove(object: Element) {
guard let index = firstIndex(of: object) else {return}
remove(at: index)
}
}
การใช้งาน:
var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"
myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]
ใช้งานได้กับประเภทอื่น ๆ เช่นInt
เนื่องจากElement
เป็นประเภททั่วไป:
var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17
myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
สำหรับ Swift4:
list = list.filter{$0 != "your Value"}
ตั้งแต่ Xcode 10+ และตามเซสชัน WWDC 2018 223 "การไพบูลย์อัลกอริธึม" จะเป็นวิธีการที่ดีในอนาคตmutating func removeAll(where predicate: (Element) throws -> Bool) rethrows
ตัวอย่างของ Apple:
var phrase = "The rain in Spain stays mainly in the plain."
let vowels: Set<Character> = ["a", "e", "i", "o", "u"]
phrase.removeAll(where: { vowels.contains($0) })
// phrase == "Th rn n Spn stys mnly n th pln."
ดังนั้นในตัวอย่างของ OP การลบสัตว์ [2], "chimps":
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }
วิธีนี้อาจเป็นที่ต้องการเนื่องจากมีการปรับขนาดได้ดี (linear vs quadratic) สามารถอ่านได้และสะอาด โปรดทราบว่าใช้งานได้เฉพาะใน Xcode 10+ เท่านั้นและในขณะที่เขียนสิ่งนี้อยู่ในรุ่นเบต้า
การดำเนินการบางอย่างเกี่ยวข้องกับ Array in Swift
สร้างอาร์เรย์
var stringArray = ["One", "Two", "Three", "Four"]
เพิ่มวัตถุในอาร์เรย์
stringArray = stringArray + ["Five"]
รับค่าจากวัตถุดัชนี
let x = stringArray[1]
ผนวกวัตถุ
stringArray.append("At last position")
แทรกวัตถุที่ดัชนี
stringArray.insert("Going", atIndex: 1)
ลบวัตถุ
stringArray.removeAtIndex(3)
ค่าวัตถุ Concat
var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
คุณสามารถทำได้ ก่อนอื่นตรวจสอบให้แน่ใจว่าDog
มีอยู่จริงในอาร์เรย์แล้วลบออก เพิ่มfor
คำสั่งถ้าคุณเชื่อว่าDog
อาจเกิดขึ้นมากกว่าหนึ่งครั้งในอาร์เรย์ของคุณ
var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"
for object in animals
{
if object == animalToRemove{
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
}
}
หากคุณแน่ใจว่าDog
ออกจากอาร์เรย์แล้วเกิดขึ้นเพียงครั้งเดียว:
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
หากคุณมีทั้งสตริงและตัวเลข
var array = [12, 23, "Dog", 78, 23]
let numberToRemove = 23
let animalToRemove = "Dog"
for object in array
{
if object is Int
{
// this will deal with integer. You can change to Float, Bool, etc...
if object == numberToRemove
{
array.removeAtIndex(array.indexOf(numberToRemove)!)
}
}
if object is String
{
// this will deal with strings
if object == animalToRemove
{
array.removeAtIndex(array.indexOf(animalToRemove)!)
}
}
}
หากคุณไม่รู้จักดัชนีขององค์ประกอบที่คุณต้องการลบและองค์ประกอบนั้นสอดคล้องกับโปรโตคอล Equatable คุณสามารถทำได้:
animals.removeAtIndex(animals.indexOf("dogs")!)
ดูคำตอบโปรโตคอลที่เท่าเทียมกัน: ฉันจะทำ indexOfObject หรือมีOffjectที่เหมาะสมได้อย่างไร
ลบองค์ประกอบโดยใช้อาร์เรย์ดัชนี:
Array of Strings และดรรชนี
let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"]
let indexAnimals = [0, 3, 4]
let arrayRemainingAnimals = animals
.enumerated()
.filter { !indexAnimals.contains($0.offset) }
.map { $0.element }
print(arrayRemainingAnimals)
//result - ["dogs", "chimps", "cow"]
อาร์เรย์ของจำนวนเต็มและดัชนี
var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let indexesToRemove = [3, 5, 8, 12]
numbers = numbers
.enumerated()
.filter { !indexesToRemove.contains($0.offset) }
.map { $0.element }
print(numbers)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
ลบองค์ประกอบโดยใช้ค่าองค์ประกอบของอาร์เรย์อื่น
อาร์เรย์ของจำนวนเต็ม
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
อาร์เรย์ของสตริง
let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
let arrayRemoveLetters = ["a", "e", "g", "h"]
let arrayRemainingLetters = arrayLetters.filter {
!arrayRemoveLetters.contains($0)
}
print(arrayRemainingLetters)
//result - ["b", "c", "d", "f", "i"]
เกี่ยวกับทางเลือกของ @ Suragch ในการ "ลบองค์ประกอบของดัชนีที่ไม่รู้จัก":
มี "indexOf (องค์ประกอบ)" รุ่นที่มีประสิทธิภาพมากกว่าที่จะจับคู่กับเพรดิเคตแทนที่จะเป็นวัตถุ มันใช้ชื่อเดียวกัน แต่ถูกเรียกโดย myObjects.indexOf {$ 0.property = valueToMatch} มันจะส่งคืนดัชนีของรายการแรกที่พบในอาร์เรย์ myObjects
หากองค์ประกอบนั้นเป็นวัตถุ / โครงสร้างคุณอาจต้องการลบองค์ประกอบนั้นตามมูลค่าของคุณสมบัติอย่างใดอย่างหนึ่ง เช่นคุณมีคลาสรถยนต์ที่มีคุณสมบัติ car.color และคุณต้องการลบรถ "สีแดง" ออกจากรถของคุณอาเรย์
if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}
ก่อนหน้านี้คุณสามารถทำสิ่งนี้ใหม่เพื่อลบรถสีแดง "ทั้งหมด" โดยการฝังคำสั่งด้านบนหากมีการวนซ้ำในขณะที่วนซ้ำและแนบบล็อกอื่นเพื่อตั้งค่าสถานะเป็น "แยก" ออกจากวง
สวิฟท์ 5
guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)
หากคุณมีอาร์เรย์ของวัตถุที่กำหนดเองคุณสามารถค้นหาตามคุณสมบัติเฉพาะเช่นนี้:
if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
doctorsInArea.removeAtIndex(index)
}
หรือถ้าคุณต้องการค้นหาตามชื่อ
if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
doctorsInArea.removeAtIndex(index)
}
สิ่งนี้ควรทำ (ไม่ได้ทดสอบ):
animals[2..3] = []
แก้ไข: และคุณต้องทำให้เป็นvar
ไม่ใช่ไม่ใช่let
หรือเป็นค่าคงที่ไม่เปลี่ยนรูป
ฉันมาพร้อมกับส่วนขยายต่อไปนี้ที่ดูแลการลบองค์ประกอบออกจากArray
สมมติว่าองค์ประกอบในการArray
ใช้งานEquatable
:
extension Array where Element: Equatable {
mutating func removeEqualItems(item: Element) {
self = self.filter { (currentItem: Element) -> Bool in
return currentItem != item
}
}
mutating func removeFirstEqualItem(item: Element) {
guard var currentItem = self.first else { return }
var index = 0
while currentItem != item {
index += 1
currentItem = self[index]
}
self.removeAtIndex(index)
}
}
var test1 = [1, 2, 1, 2]
test1.removeEqualItems(2) // [1, 1]
var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]
ส่วนขยายเพื่อลบวัตถุสตริง
extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}
ฉันใช้ส่วนขยายนี้เกือบเหมือนกับ Varun แต่อันนี้ (ด้านล่าง) เป็นจุดประสงค์ทั้งหมด:
extension Array where Element: Equatable {
mutating func delete(element: Iterator.Element) {
self = self.filter{$0 != element }
}
}
ในการลบองค์ประกอบจากอาร์เรย์ใช้remove(at:)
,
และremoveLast()
removeAll()
yourArray = [1,2,3,4]
ลบค่าที่ 2 ตำแหน่ง
yourArray.remove(at: 2)
ลบค่าสุดท้ายออกจากอาร์เรย์
yourArray.removeLast()
ลบสมาชิกทั้งหมดออกจากชุด
yourArray.removeAll()
remove
ส่งคืนองค์ประกอบที่ถูกลบ:let animal = animals.remove(at: 2)