Antworten:
Da Swift in mancher Hinsicht funktionaler als objektorientiert ist (und Arrays Strukturen und keine Objekte sind), verwenden Sie die Funktion "find", um das Array zu bearbeiten, das einen optionalen Wert zurückgibt. Seien Sie also darauf vorbereitet, einen Nullwert zu verarbeiten:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Update für Swift 2.0:
Die alte find
Funktion wird mit Swift 2.0 nicht mehr unterstützt!
Mit Swift 2.0 können Array
Sie den Index eines Elements mithilfe einer Funktion ermitteln, die in einer Erweiterung von CollectionType
(die Array
implementiert) definiert ist:
let arr = ["a","b","c"]
let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil
Darüber hinaus wird das Finden des ersten Elements in einem Array, das ein Prädikat erfüllt, durch eine andere Erweiterung von unterstützt CollectionType
:
let arr2 = [1,2,3,4,5,6,7,8,9,10]
let indexOfFirstGreaterThanFive = arr2.indexOf({$0 > 5}) // 5
let indexOfFirstGreaterThanOneHundred = arr2.indexOf({$0 > 100}) // nil
Beachten Sie, dass diese beiden Funktionen find
wie zuvor optionale Werte zurückgeben .
Update für Swift 3.0:
Beachten Sie, dass sich die Syntax von indexOf geändert hat. Für Artikel, die Ihren Anforderungen entsprechen, können Equatable
Sie Folgendes verwenden:
let indexOfA = arr.index(of: "a")
Eine ausführliche Dokumentation der Methode finden Sie unter https://developer.apple.com/reference/swift/array/1689674-index
Für Array-Elemente, die nicht den Equatable
Anforderungen entsprechen, müssen Sie Folgendes verwenden index(where:)
:
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you're looking for
})
Update für Swift 4.2:
Wird mit Swift 4.2 index
nicht mehr verwendet, sondern zur besseren Verdeutlichung in firstIndex
und getrennt lastIndex
. Je nachdem, ob Sie nach dem ersten oder dem letzten Index des Artikels suchen:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
indexOf
Ihrer Information : Wenn Sie ein Array von Strukturen verwenden, die Sie selbst definiert haben, muss Ihre Struktur dem Equatable
Protokoll entsprechen.
tl; dr:
Für Klassen suchen Sie möglicherweise:
let index = someArray.firstIndex{$0 === someObject}
Vollständige Antwort:
Ich denke, es ist erwähnenswert, dass Sie mit Referenztypen ( class
) möglicherweise einen Identitätsvergleich durchführen möchten. In diesem Fall müssen Sie nur den ===
Identitätsoperator beim Schließen des Prädikats verwenden:
Swift 5, Swift 4.2:
let person1 = Person(name: "John")
let person2 = Person(name: "Sue")
let person3 = Person(name: "Maria")
let person4 = Person(name: "Loner")
let people = [person1, person2, person3]
let indexOfPerson1 = people.firstIndex{$0 === person1} // 0
let indexOfPerson2 = people.firstIndex{$0 === person2} // 1
let indexOfPerson3 = people.firstIndex{$0 === person3} // 2
let indexOfPerson4 = people.firstIndex{$0 === person4} // nil
Beachten Sie, dass die obige Syntax die Syntax für abschließende Verschlüsse verwendet und Folgendes entspricht:
let indexOfPerson1 = people.firstIndex(where: {$0 === person1})
Swift 4 / Swift 3 - die Funktion, die früher aufgerufen wurde index
Swift 2 - die Funktion, die früher aufgerufen wurde indexOf
* Beachten Sie den relevanten und nützlichen Kommentar von paulbailey zu class
implementierten Typen Equatable
, bei dem Sie überlegen müssen, ob Sie mit ===
( Identitätsoperator ) oder ==
( Gleichheitsoperator ) vergleichen sollten. Wenn Sie sich für eine Übereinstimmung mit entscheiden, ==
können Sie einfach die von anderen vorgeschlagene Methode verwenden ( people.firstIndex(of: person1)
).
Person
das Equatable
Protokoll implementiert wäre, wäre dies nicht erforderlich.
Binary operator '===' cannot be applied to operands of type '_' and 'Post'
, Post
meine Struktur ist ... eine Idee?
structs
(und enums
) sind Werttypen, keine Referenztypen. Nur Referenztypen (z. B. class
) haben eine Identitätsvergleichslogik ( ===
). Schauen Sie sich die anderen Antworten an, um zu erfahren, was Sie tun sollen structs
(im Grunde verwenden Sie einfach die array.index(of: myStruct)
, um sicherzustellen, dass der Typ myStruct
mit Equatable
( ==
) übereinstimmt ).
Sie können filter
ein Array mit einem Abschluss erstellen:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
Und Sie können ein Array zählen:
filtered.count // <= returns 1
Sie können also feststellen, ob ein Array Ihr Element enthält, indem Sie diese kombinieren:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
Wenn Sie die Position finden wollen, sehe ich keinen ausgefallenen Weg, aber Sie können es auf jeden Fall so machen:
var found: Int? // <= will hold the index if it was found, or else will be nil
for i in (0..x.count) {
if x[i] == 3 {
found = i
}
}
BEARBEITEN
Während wir gerade dabei sind, wollen wir für eine lustige Übung Array
eine find
Methode erweitern:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
Jetzt können wir das tun:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
Array
um eine find
Methode erweitere, die das tut, was Sie wollen. Ich weiß noch nicht, ob dies eine gute Praxis ist, aber es ist ein ordentliches Experiment.
enumerate
damit es nicht mehr gilt, aber Sie haben absolut Recht.
func firstIndex(of element: Element) -> Int?
var alphabets = ["A", "B", "E", "D"]
Beispiel 1
let index = alphabets.firstIndex(where: {$0 == "A"})
Beispiel2
if let i = alphabets.firstIndex(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
Funktioniert zwar indexOf()
einwandfrei, gibt jedoch nur einen Index zurück.
Ich suchte nach einer eleganten Möglichkeit, eine Reihe von Indizes für Elemente zu erhalten, die bestimmte Bedingungen erfüllen.
So geht's:
Swift 3:
let array = ["apple", "dog", "log"]
let indexes = array.enumerated().filter {
$0.element.contains("og")
}.map{$0.offset}
print(indexes)
Swift 2:
let array = ["apple", "dog", "log"]
let indexes = array.enumerate().filter {
$0.element.containsString("og")
}.map{$0.index}
print(indexes)
Für benutzerdefinierte Klassen müssen Sie das Equatable-Protokoll implementieren.
import Foundation
func ==(l: MyClass, r: MyClass) -> Bool {
return l.id == r.id
}
class MyClass: Equtable {
init(id: String) {
self.msgID = id
}
let msgID: String
}
let item = MyClass(3)
let itemList = [MyClass(1), MyClass(2), item]
let idx = itemList.indexOf(item)
printl(idx)
Update für Swift 2:
sequence.contains (element) : Gibt true zurück, wenn eine bestimmte Sequenz (z. B. ein Array) das angegebene Element enthält.
Swift 1:
Wenn Sie nur überprüfen möchten, ob ein Element in einem Array enthalten ist, dh nur einen booleschen Indikator erhalten, verwenden Sie contains(sequence, element)
anstelle von find(array, element)
:
enthält (Sequenz, Element) : Gibt true zurück, wenn eine bestimmte Sequenz (z. B. ein Array) das angegebene Element enthält.
Siehe Beispiel unten:
var languages = ["Swift", "Objective-C"]
contains(languages, "Swift") == true
contains(languages, "Java") == false
contains([29, 85, 42, 96, 75], 42) == true
if (contains(languages, "Swift")) {
// Use contains in these cases, instead of find.
}
in Swift 4.2
.index (wo :) wurde in .firstIndex (wo :) geändert
array.firstIndex(where: {$0 == "person1"})
Swift 4. Wenn Ihr Array Elemente vom Typ [String: AnyObject] enthält. Um den Index des Elements zu finden, verwenden Sie den folgenden Code
var array = [[String: AnyObject]]()// Save your data in array
let objectAtZero = array[0] // get first object
let index = (self.array as NSArray).index(of: objectAtZero)
Oder Wenn Sie einen Index auf der Grundlage eines Schlüssels aus dem Wörterbuch finden möchten. Hier enthält das Array Objekte der Modellklasse und ich stimme mit der ID-Eigenschaft überein.
let userId = 20
if let index = array.index(where: { (dict) -> Bool in
return dict.id == userId // Will found index of matched id
}) {
print("Index found")
}
OR
let storeId = Int(surveyCurrent.store_id) // Accessing model key value
indexArrUpTo = self.arrEarnUpTo.index { Int($0.store_id) == storeId }! // Array contains models and finding specific one
Swift 2.1
var array = ["0","1","2","3"]
if let index = array.indexOf("1") {
array.removeAtIndex(index)
}
print(array) // ["0","2","3"]
Swift 3
var array = ["0","1","2","3"]
if let index = array.index(of: "1") {
array.remove(at: index)
}
array.remove(at: 1)
let array
? Die Verwendung von self
ist ebenfalls fraglich.
Wenn Sie in Swift 4 Ihr DataModel-Array durchlaufen, stellen Sie sicher, dass Ihr Datenmodell dem Equatable Protocol entspricht, implementieren Sie die Methode lhs = rhs, und nur dann können Sie beispielsweise ".index (of") verwenden
class Photo : Equatable{
var imageURL: URL?
init(imageURL: URL){
self.imageURL = imageURL
}
static func == (lhs: Photo, rhs: Photo) -> Bool{
return lhs.imageURL == rhs.imageURL
}
}
Und dann,
let index = self.photos.index(of: aPhoto)
Array
Enthält in Swift 2 (mit Xcode 7) eine indexOf
vom CollectionType
Protokoll bereitgestellte Methode . (Tatsächlich zwei indexOf
Methoden - eine, die Gleichheit verwendet, um einem Argument zu entsprechen, und eine andere , die einen Abschluss verwendet.)
Vor Swift 2 gab es für generische Typen wie Sammlungen keine Möglichkeit, Methoden für die daraus abgeleiteten konkreten Typen (wie Arrays) bereitzustellen. In Swift 1.x ist "index of" eine globale Funktion ... und es wurde auch umbenannt. In Swift 1.x wird diese globale Funktion aufgerufen find
.
Es ist auch möglich (aber nicht erforderlich), die indexOfObject
Methode von NSArray
... oder eine andere, komplexere Suchmethode von Foundation zu verwenden, die keine Entsprechungen in der Swift-Standardbibliothek enthält. Nur import Foundation
(oder ein anderes Modul , dass transitively importiert Foundation), werfen Sie Ihre Array
zu NSArray
, und Sie können auf die vielen Suchmethoden verwenden NSArray
.
Jede dieser Lösungen funktioniert für mich
Dies ist die Lösung, die ich für Swift 4 habe:
let monday = Day(name: "M")
let tuesday = Day(name: "T")
let friday = Day(name: "F")
let days = [monday, tuesday, friday]
let index = days.index(where: {
//important to test with === to be sure it's the same object reference
$0 === tuesday
})
Sie können auch die Funktionsbibliothek Dollar verwenden, um einen Index für ein Array als solches zu erstellen. Http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Wenn Sie noch in Swift 1.x arbeiten
dann versuche es,
let testArray = ["A","B","C"]
let indexOfA = find(testArray, "A")
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
Für SWIFT 3 können Sie eine einfache Funktion verwenden
func find(objecToFind: String?) -> Int? {
for i in 0...arrayName.count {
if arrayName[i] == objectToFind {
return i
}
}
return nil
}
Dies gibt die Nummer Position, so dass Sie wie verwenden können
arrayName.remove(at: (find(objecToFind))!)
Ich hoffe, nützlich zu sein
SWIFT 4
Angenommen, Sie möchten eine Nummer aus dem Array cardButtons in cardNumber speichern. Dies können Sie folgendermaßen tun:
let cardNumber = cardButtons.index(of: sender)
Absender ist der Name Ihrer Schaltfläche
Verwenden Sie in Swift 4/5 "firstIndex", um den Index zu finden.
let index = array.firstIndex{$0 == value}
Falls jemand dieses Problem hat
Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'
Aber mach das
extension Int {
var toInt: Int {
return self
}
}
dann
guard let finalIndex = index?.toInt else {
return false
}
Zum (>= swift 4.0)
Es ist ziemlich einfach. Betrachten Sie das folgende Array
Objekt.
var names: [String] = ["jack", "rose", "jill"]
Um den Index des Elements zu erhalten rose
, müssen Sie lediglich Folgendes tun:
names.index(of: "rose") // returns 1
Hinweis:
Array.index(of:)
gibt ein zurück Optional<Int>
.
nil
impliziert, dass das Element nicht im Array vorhanden ist.
Möglicherweise möchten Sie den zurückgegebenen Wert zwangsweise auspacken oder ein verwenden if-let
, um das optionale zu umgehen .