Jak mogę rozbroić / usunąć element z tablicy w nowym języku Apple Swift?
Oto kod:
let animals = ["cats", "dogs", "chimps", "moose"]
Jak można animals[2]usunąć element z tablicy?
Jak mogę rozbroić / usunąć element z tablicy w nowym języku Apple Swift?
Oto kod:
let animals = ["cats", "dogs", "chimps", "moose"]
Jak można animals[2]usunąć element z tablicy?
Odpowiedzi:
Słowo letkluczowe służy do deklarowania stałych, których nie można zmienić. Jeśli chcesz zmodyfikować zmienną, powinieneś użyć varzamiast niej, np .:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.remove(at: 2) //["cats", "dogs", "moose"]
Nie mutującą alternatywą, która zachowa oryginalną kolekcję bez zmian, jest filterutworzenie nowej kolekcji bez elementów, które chcesz usunąć, np .:
let pets = animals.filter { $0 != "chimps" }
Dany
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"]
Tylko dla jednego elementu
if let index = animals.firstIndex(of: "chimps") {
animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]
Dla wielu elementów
var animals = ["cats", "dogs", "chimps", "moose", "chimps"]
animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]
filter) i zwracają usunięty element.dropFirstlub dropLastutworzyć nową tablicę.Zaktualizowano do Swift 5.2
Powyższe odpowiedzi wydają się zakładać, że znasz indeks elementu, który chcesz usunąć.
Często znasz odniesienie do obiektu, który chcesz usunąć z tablicy. (Iterowałeś przez tablicę i ją znalazłeś, np.) W takich przypadkach może być łatwiej pracować bezpośrednio z odwołaniem do obiektu bez konieczności przekazywania wszędzie jego indeksu. Dlatego proponuję to rozwiązanie. Używa operatora tożsamości !== , którego używasz do testowania, czy oba odwołania do obiektów odnoszą się do tej samej instancji obiektu.
func delete(element: String) {
list = list.filter() { $0 !== element }
}
Oczywiście to nie działa tylko dla Strings.
list = list.filter({ $0 != element })
array.indexOf({ $0 == obj })
listtego usunięcia, nie zaktualizuje innych odwołań do tablicy, ponieważ przypisujesz nową tablicę list. Tylko subtelna implikacja, jeśli usuniesz z tablic za pomocą tego podejścia.
Swift 5: Oto fajne i łatwe rozszerzenie do usuwania elementów z tablicy bez filtrowania:
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)
}
}
Stosowanie :
var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"
myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]
Działa również z innymi typami, np. IntPonieważ Elementjest to typ ogólny:
var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17
myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
W przypadku Swift4:
list = list.filter{$0 != "your Value"}
Począwszy od Xcode 10+ i zgodnie z sesją WWDC 2018 223 „Algorytmy obejmujące” dobrą metodą będziemutating func removeAll(where predicate: (Element) throws -> Bool) rethrows
Przykład 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."
widzieć dokumentacja Apple
Tak więc w przykładzie PO usunięcie zwierząt [2], „szympansów”:
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }
Ta metoda może być preferowana, ponieważ dobrze się skaluje (liniowa vs kwadratowa), jest czytelna i czysta. Pamiętaj, że działa tylko w Xcode 10+, a od momentu pisania jest w wersji beta.
Kilka operacji dotyczy tablicy w trybie Swift
Utwórz tablicę
var stringArray = ["One", "Two", "Three", "Four"]
Dodaj obiekt w szyku
stringArray = stringArray + ["Five"]
Uzyskaj wartość z obiektu indeksu
let x = stringArray[1]
Dołącz obiekt
stringArray.append("At last position")
Wstaw obiekt o indeksie
stringArray.insert("Going", atIndex: 1)
Usuń obiekt
stringArray.removeAtIndex(3)
Concat Wartość obiektu
var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
Mógłbyś to zrobić. Najpierw upewnij się, że Dognaprawdę istnieje w tablicy, a następnie usuń ją. Dodaj forinstrukcję, jeśli uważasz, że Dogmoże się zdarzyć więcej niż jeden raz na tablicy.
var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"
for object in animals
{
if object == animalToRemove{
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
}
}
Jeśli jesteś pewien, że Dogwychodzi z tablicy i zdarzyło się to tylko raz, zrób to:
animals.removeAtIndex(animals.indexOf(animalToRemove)!)
Jeśli masz zarówno ciągi, jak i liczby
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)!)
}
}
}
Jeśli nie znasz indeksu elementu, który chcesz usunąć, a element jest zgodny z protokołem Equatable, możesz:
animals.removeAtIndex(animals.indexOf("dogs")!)
Zobacz odpowiedź na protokół Equatable: Jak zrobić indexOfObject lub odpowiedni zawieraObject
Usuń elementy za pomocą tablicy indeksów:
Tablica ciągów i indeksów
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"]Tablica liczb całkowitych i indeksów
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]
Usuń elementy, używając wartości elementu innej tablicy
Tablice liczb całkowitych
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]Tablice ciągów
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"]Odnośnie alternatywy @ Suragch do „Usuń element o nieznanym indeksie”:
Istnieje mocniejsza wersja „indexOf (element)”, która będzie pasować do predykatu zamiast samego obiektu. Ma taką samą nazwę, ale jest wywoływana przez myObjects.indexOf {$ 0.property = valueToMatch}. Zwraca indeks pierwszego pasującego elementu znalezionego w tablicy myObjects.
Jeśli element jest obiektem / strukturą, możesz chcieć usunąć ten element na podstawie wartości jednej z jego właściwości. Na przykład masz klasę samochodów posiadającą właściwość car.color i chcesz usunąć „czerwony” samochód z tablicy carsArray.
if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
carsArray.removeAtIndex(validIndex)
}
Można było przewidzieć, że można to przerobić, aby usunąć „wszystkie” czerwone samochody, osadzając powyższą instrukcję if w pętli powtarzania / while i dołączając blok else, aby ustawić flagę „wyłamującą się” z pętli.
Jeśli masz szereg obiektów niestandardowych, możesz wyszukiwać według określonych właściwości, takich jak:
if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
doctorsInArea.removeAtIndex(index)
}
lub jeśli chcesz na przykład wyszukać według nazwy
if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
doctorsInArea.removeAtIndex(index)
}
Powinno to zrobić (nie przetestowane):
animals[2..3] = []
Edycja: i musisz zrobić to, a varnie let, w przeciwnym razie jest to niezmienna stała.
Wymyśliłem następujące rozszerzenie, które zajmuje się usuwaniem elementów z Array, zakładając elementy w Arraynarzędziu 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]
rozszerzenie do usunięcia obiektu String
extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}
Używam tego rozszerzenia, prawie takiego samego jak Varun, ale to (poniżej) jest uniwersalne:
extension Array where Element: Equatable {
mutating func delete(element: Iterator.Element) {
self = self.filter{$0 != element }
}
}
removezwraca usunięty element:let animal = animals.remove(at: 2)