Swift'te bir diziden bir öğe nasıl kaldırılır


236

Apple'ın yeni dili Swift'teki bir dizideki bir öğeyi nasıl kaldırabilir / kaldırabilirim?

İşte bazı kod:

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

Öğe animals[2]diziden nasıl kaldırılabilir?

Yanıtlar:


300

letAnahtar kelime değiştirilemez sabitleri ilan içindir. Bir değişkeni değiştirmek istiyorsanız varbunun yerine kullanmalısınız , örneğin:

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

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

Orijinal koleksiyonu değiştirmeden değiştirecek olmayan bir alternatif, filterkaldırmak istediğiniz öğeler olmadan yeni bir koleksiyon oluşturmak için kullanmaktır , örneğin:

let pets = animals.filter { $0 != "chimps" }

7
FYI: removekaldırılan öğeyi döndürür:let animal = animals.remove(at: 2)
2Takım

1
sadece indekse göre filtreleyebilir miyiz ??
Şakir

@shaqirsaiyed Düşünebileceğiniz herhangi bir yüklem üzerinde filtre uygulayabilirsiniz. örneğin, "s" ile biten tüm hayvanları filtreleyebilirsiniz.
Womble

hayvan ekle = evcil hayvan
Puji Wahono

197

verilmiş

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

İlk öğeyi kaldır

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

Son öğeyi kaldır

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

Dizindeki öğeyi kaldır

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

Dizini bilinmeyen öğeyi kaldır

Sadece bir eleman için

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

Birden çok eleman için

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

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

notlar

  • Yukarıdaki yöntemler diziyi yerinde değiştirir (hariç filter ) değiştirir ve kaldırılan öğeyi döndürür.
  • Harita Filtresi Azaltma için Hızlı Kılavuz
  • Orijinal diziyi değiştirmek istemiyorsanız, yeni bir dizi oluşturmak için dropFirstveya öğesini kullanabilirsiniz dropLast.

Swift 5.2 olarak güncellendi


Bu örnekler için teşekkürler , bilinmeyen dizin öğesini kaldır > içinde birden çok öğechimps && moose için, örneğin kaldırmak için hangi kapağı yazardınız? Ben farklı bir şey arıyorum{$0 != "chimps" && $0 != "moose"}

161

Yukarıdaki yanıtlar, silmek istediğiniz öğenin dizinini bildiğinizi varsayar.

Genellikle dizide silmek istediğiniz nesneye yapılan başvuruyu bilirsiniz . (Dizinizi yinelemiş ve bulmuşsunuzdur, örneğin) Bu gibi durumlarda, dizininin her yerine iletmek zorunda kalmadan doğrudan nesne başvurusu ile çalışmak daha kolay olabilir. Bu yüzden bu çözümü öneriyorum. İki nesne başvurusunun her ikisinin de aynı nesne örneğine karşılık gelip gelmediğini test etmek için kullandığınız kimlik operatörünü kullanır !==.

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

Elbette bu sadece Strings için işe yaramıyor .


23
Olmalılist = list.filter({ $0 != element })
Craig Grummitt

5
Kimlik operatörüne danışmak istemiyorsanız hayır.
Daniel

3
array.indexOf({ $0 == obj })
jrc

2
listBu silmeye başvuran diğer nesneler , yeni bir dizi atadığınız için diğer dizi başvurularını güncellemezse unutmayın list. Bu yaklaşımla dizilerden silerseniz sadece ince bir ima.
Crashalot

1
Fonksiyonel programlama paradigması değişmez nesnelere dayanır. Yani, onları değiştirmiyorsun. Bunun yerine yeni bir nesne oluşturursunuz. Silme, haritalama, azaltma vb. listesi yeni oluşturulan bir nesne olacaktır. Yukarıdaki kod snippet'inde yeni oluşturulan bir nesneyi listelemek için tekrar atarım. Bu benim için işe yarıyor, çünkü kodumu fonksiyonel programlamayı takip edecek şekilde tasarlıyorum.
Daniel

44

Swift 5: İşte bir dizideki öğeleri filtrelemeden kaldırmak için serin ve kolay bir uzantı:

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

}

Kullanımı:

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

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

Ayrıca gibi diğer türleri ile çalışır Intçünkü Elementgenel bir türüdür:

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

myArray.remove(object: objectToRemove) // [4, 8, 6, 2]

1
Elementin Eşit Olduğu Bölüm
Nicolas Manzini

1
Parlak. Protokollerin bir listesiyle başlarsanız işe yaramasa da, çünkü - Protokol türü 'Eşittir' e uygun olamaz çünkü sadece somut türler protokollere uygun olabilir :-(
AW101

22

Swift4 için:

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

15

Xcode 10+ itibariyle ve WWDC 2018 oturum 223 "Algoritmaları Kucaklamak" a göre ileriye dönük iyi bir yöntemmutating func removeAll(where predicate: (Element) throws -> Bool) rethrows

Apple örneği:

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

görmek Apple'ın Belgeleri

OP'nin örneğinde, hayvanları kaldırmak [2], "şempanzeler":

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

Bu yöntem tercih edilebilir çünkü iyi ölçeklendirilir (kuadratik ve lineer), okunabilir ve temizdir. Sadece Xcode 10+ ile çalıştığını ve bu yazının beta sürümünde olduğunu unutmayın.


removeAll (nerede :) sadece hızlı 4.2 ile mümkün olacak
Vlad Pulichev

14

Birkaç Operasyon Swift'teki Dizi ile ilgilidir

Dizi Oluştur

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

Diziye Nesne Ekle

stringArray = stringArray + ["Five"]

Dizin nesnesinden Değer Al

let x = stringArray[1]

Nesne Ekle

stringArray.append("At last position")

Dizine Nesne Ekle

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

Nesneyi Kaldır

stringArray.removeAtIndex(3)

Concat Nesne değeri

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

14

Bunu yapabilirsin. Öncelikle Dogdizide gerçekten var olduğundan emin olun , sonra kaldırın. Dizinizde birden çok kez olabileceğini fordüşünüyorsanız ifadeyi ekleyin Dog.

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

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

DogDizide çıkışlardan eminseniz ve yalnızca bir kez olduysanız, bunu yapın:

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

Hem dizeleriniz hem de numaralarınız varsa

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

Dizim Dizeler içermiyorsa ne olur?
Apqu

@apqu bir güncelleme daha yaptı '|| object == Int () 've' || object == String () 'gereksiz
GuiSoySauce

bir diziyi döngüye sokmak verimlilik kazanır. check .filter, .compactMap
MLBDG


10

Dizinler dizisini kullanarak öğeleri kaldırın:

  1. Dizeler ve dizinler dizisi

    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. Tamsayılar ve dizinler dizisi

    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]



Başka bir dizinin öğe değerini kullanarak öğeleri kaldırma

  1. Tamsayı dizileri

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

    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"]

4
Bu bir astar cevabıdır ve daha iyi kodlama ve hızlı yürütme için çok etkilidir.
iOSDev

Merhaba @Krunal - harika cevap, aşağıdaki soruya bir göz atabilir misiniz (bir görüntü dizisinden görüntüleri serbest bırakma): stackoverflow.com/questions/47735975/…
Sunucu Programcısı

6

@ Suragch'ın "Bilinmeyen endeks unsurunu kaldır" Alternatifine ilişkin olarak:

Nesnenin kendisi yerine bir yüklemle eşleşecek daha güçlü bir "indexOf (element)" sürümü vardır. Aynı adla gider, ancak myObjects.indexOf {$ 0.property = valueToMatch} tarafından çağrılır. MyObjects dizisinde bulunan ilk eşleşen öğenin dizinini döndürür.

Öğe bir nesne / yapı ise, o öğeyi özelliklerinden birinin değerine dayalı olarak kaldırmak isteyebilirsiniz. Örneğin, car.color özelliğine sahip bir Car sınıfınız var ve "kırmızı" arabayı arabalarınızdan kaldırmak istiyorsunuz.

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

Tahmin edilebilir bir şekilde, yukarıdaki if ifadesini tekrarlama / while döngüsüne gömerek ve döngüden "kırmak" için bir bayrak ayarlamak üzere başka bir blok ekleyerek "tüm" kırmızı arabaları kaldırmak için bunu yeniden çalışabilirsiniz.


6

Hızlı 5

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

4

Özel Nesneler diziniz varsa, aşağıdaki gibi belirli bir özelliğe göre arama yapabilirsiniz:

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

veya örneğin ada göre aramak istiyorsanız

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

3

Bunu yapmalı (test edilmedi):

animals[2..3] = []

Düzenleme: ve bunu yapmak gerekir var, değil let, aksi takdirde bu değişmez bir sabittir.


5
Başka bir dizi oluşturmak için mevcut bir dizinin (alt) aralığını kullanırken aralığın 3 noktaya sahip olması gerekir. Yukarıdakiler hayvan olarak yazılmalıdır [2 ... 3]
zevij

3

Bir uzantıdan öğeleri kaldırmaya özen gösteren aşağıdaki uzantı ile geldim Array öğeleri varsayarak Arrayuygulamak 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)
  }

}

Kullanımı:

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

var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]

Merhaba @nburk - harika cevap, aşağıdaki soruya bir göz atabilir misiniz (bir görüntü dizisinden görüntüleri serbest bırakma): stackoverflow.com/questions/47735975/…
Sunucu Programcısı

1

nesnesi kaldırılacak eklenti

extension Array {
    mutating func delete(element: String) {
        self = self.filter() { $0 as! String != element }
    }
}

kuvvet açmanın çökmesine neden olabilir, bence bu durumda bundan kaçınmalısınız.
user3206558

"Mutasyon yapan" işlev nedir?
AwesomeElephant8232

eskiden bu işlevin kendini (diziyi) değiştireceğini söylerdi.
Varun Naharia

1

Bu uzantıyı neredeyse Varun ile aynı şekilde kullanıyorum, ancak bu (aşağıda) çok amaçlı:

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

1

Bir dizideki öğeleri kaldırmak için remove(at:), removeLast()ve tuşlarını kullanın removeAll().

yourArray = [1,2,3,4]

2 konumda değeri kaldırın

yourArray.remove(at: 2)

Diziden son değeri kaldır

yourArray.removeLast()

Tüm üyeleri kümeden kaldırır

yourArray.removeAll()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.