Cara menghapus elemen dari array di Swift

236

Bagaimana saya bisa menghapus / menghapus elemen dari array di Swift bahasa baru Apple?

Ini beberapa kode:

let animals = ["cats", "dogs", "chimps", "moose"]

Bagaimana elemen tersebut animals[2]dapat dihapus dari array?

Leopold Joy
sumber

Jawaban:

300

Kata letkuncinya adalah untuk mendeklarasikan konstanta yang tidak dapat diubah. Jika Anda ingin memodifikasi variabel, Anda harus menggunakan var, misalnya:

var animals = ["cats", "dogs", "chimps", "moose"]

animals.remove(at: 2)  //["cats", "dogs", "moose"]

Alternatif non-mutasi yang akan membuat koleksi asli tidak berubah adalah digunakan filteruntuk membuat koleksi baru tanpa elemen yang ingin Anda hapus, misalnya:

let pets = animals.filter { $0 != "chimps" }
mitos
sumber
7
FYI: removemengembalikan elemen yang dihapus:let animal = animals.remove(at: 2)
2Muat
1
bisakah kita memfilter hanya berdasarkan indeks ??
shaqir saiyed
@shaqirsaiyed Anda dapat memfilter predikat apa pun yang dapat Anda pikirkan. misalnya Anda bisa menyaring semua hewan yang berakhiran "s".
Womble
tambahkan hewan = hewan peliharaan
Puji Wahono
197

Diberikan

var animals = ["cats", "dogs", "chimps", "moose"]

Hapus elemen pertama

animals.removeFirst() // "cats"
print(animals)        // ["dogs", "chimps", "moose"]

Hapus elemen terakhir

animals.removeLast() // "moose"
print(animals)       // ["cats", "dogs", "chimps"]

Hapus elemen pada indeks

animals.remove(at: 2) // "chimps"
print(animals)           // ["cats", "dogs", "moose"]

Hapus elemen indeks yang tidak diketahui

Hanya untuk satu elemen

if let index = animals.firstIndex(of: "chimps") {
    animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]

Untuk banyak elemen

var animals = ["cats", "dogs", "chimps", "moose", "chimps"]

animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]

Catatan

  • Metode di atas memodifikasi array di tempat (kecuali untuk filter ) dan mengembalikan elemen yang dihapus.
  • Panduan Cepat untuk Mengurangi Filter Peta
  • Jika Anda tidak ingin mengubah array asli, Anda dapat menggunakan dropFirstatau dropLastuntuk membuat array baru.

Diperbarui ke Swift 5.2

Suragch
sumber
Terima kasih atas contoh-contoh ini, di dalam Anda Hapus elemen indeks tidak dikenal > untuk banyak elemen , penutupan apa yang ingin Anda hapus chimps && moosemisalnya? Saya mencari sesuatu yang berbeda dari{$0 != "chimps" && $0 != "moose"}
161

Jawaban di atas tampaknya menganggap bahwa Anda tahu indeks elemen yang ingin Anda hapus.

Seringkali Anda tahu referensi ke objek yang ingin Anda hapus dalam array. (Anda mengulangi melalui array Anda dan telah menemukannya, misalnya) Dalam kasus seperti itu mungkin lebih mudah untuk bekerja secara langsung dengan referensi objek tanpa juga harus melewati indeksnya di mana-mana. Oleh karena itu, saya menyarankan solusi ini. Ini menggunakan operator identitas !== , yang Anda gunakan untuk menguji apakah dua referensi objek keduanya merujuk ke instance objek yang sama.

func delete(element: String) {
    list = list.filter() { $0 !== element }
}

Tentu saja ini tidak hanya bekerja untuk Strings.

Daniel
sumber
23
Seharusnyalist = list.filter({ $0 != element })
Craig Grummitt
5
Tidak jika Anda ingin memeriksa dengan operator identitas.
Daniel
3
array.indexOf({ $0 == obj })
jrc
2
Catatan jika objek lain merujuk listpenghapusan ini tidak akan memperbarui referensi array lain karena Anda menugaskan array baru list. Implikasi yang halus jika Anda menghapus dari array dengan pendekatan ini.
Crashalot
1
Paradigma pemrograman fungsional bergantung pada objek yang tidak dapat diubah. Yaitu, Anda tidak mengubahnya. Sebaliknya, Anda membuat objek baru. Inilah yang dihapus, petakan, kurangi, dll. daftar akan menjadi objek yang baru dibuat. Dalam cuplikan kode di atas, saya menetapkan kembali ke daftar objek yang baru dibuat. Itu bekerja untuk saya, karena saya merancang kode saya dengan cara yang mengikuti pemrograman fungsional.
Daniel
44

Swift 5: Berikut ini adalah ekstensi keren dan mudah untuk menghapus elemen dalam array, tanpa pemfilteran:

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

}

Penggunaan:

var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"

myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]

Juga berfungsi dengan tipe lain, seperti Intkarena Elementini adalah tipe generik:

var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17

myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
Skaal
sumber
1
Menarik Array ini tempat Elemen: Bagian yang Setara
Nicolas Manzini
1
Cemerlang. Meskipun itu tidak berfungsi jika Anda mulai dengan daftar Protokol, karena - Tipe protokol tidak dapat memenuhi 'Equatable' karena hanya tipe konkret yang dapat memenuhi protokol :-(
AW101
22

Untuk Swift4:

list = list.filter{$0 != "your Value"}

sumber
15

Pada Xcode 10+, dan menurut sesi WWDC 2018 223, "Merangkul Algoritma," metode yang baik ke depan adalahmutating func removeAll(where predicate: (Element) throws -> Bool) rethrows

Contoh 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."

lihat Dokumentasi Apple

Jadi dalam contoh OP, menghilangkan hewan [2], "simpanse":

var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }

Metode ini lebih disukai karena berskala baik (linear vs kuadrat), mudah dibaca dan bersih. Ingatlah bahwa ini hanya berfungsi di Xcode 10+, dan saat penulisan ini masih dalam Beta.

davidrynn
sumber
removeAll (di mana :) hanya bisa di swift 4.2
Vlad Pulichev
14

Beberapa Operasi terkait dengan Array di Swift

Buat Array

var stringArray = ["One", "Two", "Three", "Four"]

Tambahkan Objek di Array

stringArray = stringArray + ["Five"]

Dapatkan Nilai dari objek Indeks

let x = stringArray[1]

Tambahkan Objek

stringArray.append("At last position")

Masukkan Objek di Indeks

stringArray.insert("Going", atIndex: 1)

Hapus Objek

stringArray.removeAtIndex(3)

Nilai Objek Concat

var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
Padat Lembut
sumber
14

Anda bisa melakukannya. Pertama-tama pastikan Dogbenar-benar ada dalam array, lalu hapus. Tambahkan forpernyataan jika Anda yakin Dogdapat terjadi lebih dari satu kali pada array Anda.

var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"

for object in animals
{
    if object == animalToRemove{
        animals.removeAtIndex(animals.indexOf(animalToRemove)!)
    }
}

Jika Anda yakin Dogkeluar dalam array dan terjadi hanya sekali lakukan saja:

animals.removeAtIndex(animals.indexOf(animalToRemove)!)

Jika Anda memiliki keduanya, string dan angka

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)!)
        }
    }
}
GuiSoySauce
sumber
Bagaimana jika array saya tidak mengandung Strings?
Apqu
@apqu melakukan pembaruan lainnya '|| object == Int () 'dan' || object == String () 'tidak perlu
GuiSoySauce
pengulangan array berjalan melawan efisiensi. periksa .filter, .compactMap
MLBDG
10

Hapus elemen menggunakan array indeks:

  1. Array String dan indeks

    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"]
  2. Array bilangan bulat dan indeks

    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]



Hapus elemen menggunakan nilai elemen array lain

  1. Susunan bilangan bulat

    let arrayResult = numbers.filter { element in
        return !indexesToRemove.contains(element)
    }
    print(arrayResult)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
  2. Susunan string

    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"]
Krunal
sumber
4
Ini adalah satu jawaban liner dan jauh lebih efisien untuk pengkodean yang lebih baik dan eksekusi cepat.
The iOSDev
Hai @ Kwrunal - jawaban yang bagus, dapatkah Anda melihat pertanyaan berikut (melepaskan gambar dari susunan gambar): stackoverflow.com/questions/47735975/…
Server Programmer
6

Mengenai @ Suragch's Alternatif untuk "Hapus elemen indeks tidak dikenal":

Ada versi "indexOf (elemen)" yang lebih kuat yang akan cocok dengan predikat daripada objek itu sendiri. Itu berjalan dengan nama yang sama tetapi dipanggil oleh myObjects.indexOf {$ 0.property = valueToMatch}. Ini mengembalikan indeks item yang cocok pertama kali ditemukan di array myObjects.

Jika elemen adalah objek / struct, Anda mungkin ingin menghapus elemen itu berdasarkan nilai salah satu propertinya. Misalnya, Anda memiliki kelas mobil yang memiliki properti car.color, dan Anda ingin menghapus mobil "merah" dari mobil Anda.

if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
  carsArray.removeAtIndex(validIndex)
}

Sudah bisa diduga, Anda bisa mengerjakan ulang ini untuk menghapus "semua" mobil merah dengan menyematkan pernyataan if di atas dalam loop repeat / while, dan melampirkan blok lain untuk mengatur flag untuk "break" keluar dari loop.

ObjectiveTC
sumber
6

Cepat 5

guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)
Jerome
sumber
4

Jika Anda memiliki berbagai objek kustom, Anda dapat mencari berdasarkan properti tertentu seperti ini:

    if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
        doctorsInArea.removeAtIndex(index)
    }

atau jika Anda ingin mencari berdasarkan nama misalnya

    if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
        doctorsInArea.removeAtIndex(index)
    }
Abo3atef
sumber
3

Ini harus dilakukan (tidak diuji):

animals[2..3] = []

Sunting: dan Anda harus membuatnya var, bukan a let, jika tidak, konstanta yang abadi.

File Analog
sumber
5
Saat menggunakan rentang (sub) dari array yang ada untuk membuat array lain, rentang perlu memiliki 3 titik. Yang di atas harus ditulis sebagai binatang [2 ... 3]
zevij
3

Saya datang dengan ekstensi berikut yang menangani penghapusan elemen dari Array, dengan asumsi elemen dalam Arrayimplement 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)
  }

}

Pemakaian:

var test1 = [1, 2, 1, 2]
test1.removeEqualItems(2) // [1, 1]

var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]
nburk
sumber
Hai @nburk - jawaban yang bagus, dapatkah Anda melihat pertanyaan berikut (melepaskan gambar dari susunan gambar): stackoverflow.com/questions/47735975/…
Server Programmer
1

ekstensi untuk menghapus objek String

extension Array {
    mutating func delete(element: String) {
        self = self.filter() { $0 as! String != element }
    }
}
Varun Naharia
sumber
buka paksa bisa menyebabkan crash, saya pikir Anda harus menghindarinya dalam kasus ini.
user3206558
Apa itu fungsi "bermutasi"?
AwesomeElephant8232
dulu ia memberi tahu bahwa fungsi ini akan mengubah diri (array).
Varun Naharia
1

Saya menggunakan ekstensi ini, hampir sama dengan Varun, tetapi yang ini (di bawah) serba guna:

 extension Array where Element: Equatable  {
        mutating func delete(element: Iterator.Element) {
                self = self.filter{$0 != element }
        }
    }
pengguna3206558
sumber
1

Untuk menghapus elemen dari array, gunakan remove(at:), removeLast()dan removeAll().

yourArray = [1,2,3,4]

Hapus nilai pada 2 posisi

yourArray.remove(at: 2)

Hapus nilai terakhir dari array

yourArray.removeLast()

Menghapus semua anggota dari set

yourArray.removeAll()
PatelFab
sumber