W mojej aplikacji dodałem jeden obiekt w tablicy po zaznaczeniu komórki i odznaczeniu i usunięciu obiektu po ponownym wybraniu komórki. Użyłem tego kodu, ale daj mi błąd.
extension Array {
func indexOfObject(object : AnyObject) -> NSInteger {
return (self as NSArray).indexOfObject(object)
}
mutating func removeObject(object : AnyObject) {
for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object) {
self.removeAtIndex(index)
}
}
}
class MyViewController: UITableViewController {
var arrContacts: [Any] = []
var contacts: [Any] = []
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
arrContacts.removeObject(contacts[indexPath.row])
}
}
Daje mi 2 takie błędy:
C-style for statement has been removed in Swift 3
Value of type '[Any]' has no member 'removeObject'
Set<Contact>
raczej niż Array. Czy możesz podać więcej informacji na temat przedmiotu kontaktu? Jeśli zrobiłeś to sam, będziesz potrzebować go, aby dostosować sięHashable
iEquatable
umieścić go w zestawieOdpowiedzi:
Swift odpowiednikiem
NSMutableArray
'sremoveObject
to:var array = ["alpha", "beta", "gamma"] if let index = array.firstIndex(of: "beta") { array.remove(at: index) }
jeśli obiekty są unikalne . W ogóle nie ma potrzeby rzucania
NSArray
i używaniaindexOfObject:
Interfejs API
index(of:
również działa, ale powoduje to niepotrzebne niejawne rzutowanie mostu doNSArray
.Jeśli istnieje wiele wystąpień tego samego obiektu, użyj
filter
. Jednak w przypadkach, takich jak tablice źródeł danych, w których indeks jest powiązany z określonym obiektem,firstIndex(of
jest preferowany, ponieważ jest szybszy niżfilter
.Aktualizacja:
W Swift 4.2+ możesz usunąć jedno lub wiele wystąpień za
beta
pomocąremoveAll(where:)
:array.removeAll{$0 == "beta"}
źródło
.index(of:
jest dostępny tylko wtedy, gdy kolekcja zawieraEquatable
typy.while let index = array.index(of: "beta") { array.remove(at: index) }
filter
rozwiązania. Ale jeśli przedmioty są wyjątkowe, zawsze używaj ich,index(of
ponieważ są znacznie bardziej wydajne niżfilter
var a = ["one", "two", "three", "four", "five"] // Remove/filter item with value 'three' a = a.filter { $0 != "three" }
źródło
W przypadku Swift 3 możesz użyć indeksu (gdzie :) i dołączyć zamknięcie, które porównuje obiekt w tablicy ($ 0) z tym, czego szukasz.
var array = ["alpha", "beta", "gamma"] if let index = array.index(where: {$0 == "beta"}) { array.remove(at: index) }
źródło
Kolejnym fajnym i przydatnym rozwiązaniem jest stworzenie takiego rozszerzenia:
extension Array where Element: Equatable { @discardableResult mutating func remove(object: Element) -> Bool { if let index = index(of: object) { self.remove(at: index) return true } return false } @discardableResult mutating func remove(where predicate: (Array.Iterator.Element) -> Bool) -> Bool { if let index = self.index(where: { (element) -> Bool in return predicate(element) }) { self.remove(at: index) return true } return false } }
W ten sposób, jeśli masz tablicę z niestandardowymi obiektami:
let obj1 = MyObject(id: 1) let obj2 = MyObject(id: 2) var array: [MyObject] = [obj1, obj2] array.remove(where: { (obj) -> Bool in return obj.id == 1 }) // OR array.remove(object: obj2)
źródło
remove(element: Element)
ponieważ w Array możesz przechowywać również typy takie jak Int, Double - nie są to obiekty.W Swift 5 użyj tego
Extension
:extension Array where Element: Equatable{ mutating func remove (element: Element) { if let i = self.firstIndex(of: element) { self.remove(at: i) } } }
przykład:
var array = ["alpha", "beta", "gamma"] array.remove(element: "beta")
W Swift 3 użyj tego
Extension
:extension Array where Element: Equatable{ mutating func remove (element: Element) { if let i = self.index(of: element) { self.remove(at: i) } } }
przykład:
var array = ["alpha", "beta", "gamma"] array.remove(element: "beta")
źródło
for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object)
jest dla pętli w stylu C i został usuniętyZmień kod na coś takiego, aby usunąć wszystkie podobne obiekty, jeśli zostały zapętlone:
let indexes = arrContacts.enumerated().filter { $0.element == contacts[indexPath.row] }.map{ $0.offset } for index in indexes.reversed() { arrContacts.remove(at: index) }
źródło
Szybki 4
var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"] if let index = students.firstIndex(where: { $0.hasPrefix("A") }) { students.remove(at: index) }
źródło
Prawidłowe i działające jednowierszowe rozwiązanie do usuwania unikalnego obiektu (o nazwie „objectToRemove”) z tablicy tych obiektów (o nazwie „tablica”) w języku Swift 3 to:
if let index = array.enumerated().filter( { $0.element === objectToRemove }).map({ $0.offset }).first { array.remove(at: index) }
źródło
Spróbuj tego w Swift 3
array.remove(at: Index)
Zamiast
Aktualizacja
"Declaration is only valid at file scope".
Upewnij się, że obiekt jest w zasięgu. Możesz określić zakres jako „wewnętrzny”, co jest wartością domyślną.
index(of:<Object>)
do pracy, klasa powinna się dostosowaćEquatable
źródło
W Swift 3 i 4
var array = ["a", "b", "c", "d", "e", "f"] for (index, element) in array.enumerated().reversed() { array.remove(at: index) }
Od wersji Swift 4.2 możesz zastosować bardziej zaawansowane podejście (szybsze i wydajniejsze pod względem pamięci)
array.removeAll(where: { $0 == "c" })
zamiast
array = array.filter { !$0.hasPrefix("c") }
Przeczytaj więcej tutaj
źródło
Rozszerzenie dla array, aby zrobić to łatwo i umożliwić łączenie w łańcuch dla Swift 4.2 i nowszych:
public extension Array where Element: Equatable { @discardableResult public mutating func remove(_ item: Element) -> Array { if let index = firstIndex(where: { item == $0 }) { remove(at: index) } return self } @discardableResult public mutating func removeAll(_ item: Element) -> Array { removeAll(where: { item == $0 }) return self } }
źródło
To jest oficjalna odpowiedź na znalezienie indeksu konkretnego obiektu, wtedy możesz łatwo usunąć dowolny obiekt używając tego indeksu:
var students = ["Ben", "Ivy", "Jordell", "Maxime"] if let i = students.firstIndex(of: "Maxime") { // students[i] = "Max" students.remove(at: i) } print(students) // Prints ["Ben", "Ivy", "Jordell"]
Oto link: https://developer.apple.com/documentation/swift/array/2994720-firstindex
źródło
To jest to, czego użyłem (Swift 5) ...
extension Array where Element:Equatable { @discardableResult mutating func removeFirst(_ item:Any ) -> Any? { for index in 0..<self.count { if(item as? Element == self[index]) { return self.remove(at: index) } } return nil } @discardableResult mutating func removeLast(_ item:Any ) -> Any? { var index = self.count-1 while index >= 0 { if(item as? Element == self[index]) { return self.remove(at: index) } index -= 1 } return nil } } var arrContacts:[String] = ["A","B","D","C","B","D"] var contacts: [Any] = ["B","D"] print(arrContacts) var index = 1 arrContacts.removeFirst(contacts[index]) print(arrContacts) index = 0 arrContacts.removeLast(contacts[index]) print(arrContacts)
Wyniki:
["A", "B", "D", "C", "B", "D"] ["A", "B", "C", "B", "D"] ["A", "B", "C", "D"]
Ważne: tablica, z której usuwasz elementy, musi zawierać elementy Equatable (takie jak obiekty, ciągi znaków, liczba itp.)
źródło