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 let
kluczowe służy do deklarowania stałych, których nie można zmienić. Jeśli chcesz zmodyfikować zmienną, powinieneś użyć var
zamiast 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 filter
utworzenie 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.dropFirst
lub dropLast
utworzyć 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 String
s.
list = list.filter({ $0 != element })
array.indexOf({ $0 == obj })
list
tego 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. Int
Ponieważ Element
jest 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 Dog
naprawdę istnieje w tablicy, a następnie usuń ją. Dodaj for
instrukcję, jeśli uważasz, że Dog
moż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 Dog
wychodzi 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 var
nie 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 Array
narzę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 }
}
}
remove
zwraca usunięty element:let animal = animals.remove(at: 2)