Jawaban:
Karena swift dalam beberapa hal lebih fungsional daripada berorientasi objek (dan Array adalah struct, bukan objek), gunakan fungsi "find" untuk beroperasi pada array, yang mengembalikan nilai opsional, jadi bersiaplah untuk menangani nilai nil:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Pembaruan untuk Swift 2.0:
Fungsi lama find
tidak didukung lagi dengan Swift 2.0!
Dengan Swift 2.0, Array
memperoleh kemampuan untuk menemukan indeks elemen menggunakan fungsi yang didefinisikan dalam ekstensi CollectionType
(yang Array
mengimplementasikan):
let arr = ["a","b","c"]
let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil
Selain itu, menemukan elemen pertama dalam array yang memenuhi predikat didukung oleh ekstensi lain dari 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
Perhatikan bahwa kedua fungsi ini mengembalikan nilai opsional, seperti yang find
dilakukan sebelumnya.
Pembaruan untuk Swift 3.0:
Perhatikan sintaks indexOf telah berubah. Untuk item yang sesuai dengan Equatable
Anda dapat menggunakan:
let indexOfA = arr.index(of: "a")
Dokumentasi terperinci dari metode ini dapat ditemukan di https://developer.apple.com/reference/swift/array/1689674-index
Untuk item array yang tidak sesuai dengan Equatable
Anda harus menggunakan index(where:)
:
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you're looking for
})
Pembaruan untuk Swift 4.2:
Dengan Swift 4.2, index
tidak lagi digunakan tetapi dipisahkan menjadi firstIndex
dan lastIndex
untuk klarifikasi yang lebih baik. Jadi tergantung pada apakah Anda mencari indeks item pertama atau terakhir:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
indexOf
array struct yang Anda tentukan sendiri, struct Anda harus mematuhi Equatable
protokol.
tl; dr:
Untuk kelas, Anda mungkin mencari:
let index = someArray.firstIndex{$0 === someObject}
Jawaban lengkap:
Saya pikir perlu disebutkan bahwa dengan tipe referensi ( class
) Anda mungkin ingin melakukan perbandingan identitas , dalam hal ini Anda hanya perlu menggunakan ===
operator identitas dalam penutupan predikat:
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
Perhatikan bahwa sintaks di atas menggunakan sintaks trailing closure, dan setara dengan:
let indexOfPerson1 = people.firstIndex(where: {$0 === person1})
Swift 4 / Swift 3 - fungsi yang dulu disebut index
Swift 2 - fungsi yang dulu disebut indexOf
* Catat komentar yang relevan dan berguna oleh paulbailey tentang class
jenis yang diterapkan Equatable
, di mana Anda perlu mempertimbangkan apakah Anda harus membandingkan penggunaan ===
( operator identitas ) atau ==
( operator kesetaraan ). Jika Anda memutuskan untuk mencocokkan menggunakan ==
, maka Anda cukup menggunakan metode yang disarankan oleh orang lain ( people.firstIndex(of: person1)
).
Person
menerapkan Equatable
protokol, ini tidak diperlukan.
Binary operator '===' cannot be applied to operands of type '_' and 'Post'
, Post
adalah struct saya ... ide?
structs
(dan enums
) adalah tipe nilai, bukan tipe referensi. Hanya tipe referensi (mis. class
) Yang memiliki logika perbandingan identitas ( ===
). Lihat jawaban lain untuk apa yang harus dilakukan structs
(pada dasarnya Anda cukup menggunakan array.index(of: myStruct)
, pastikan jenis myStruct
konformat ke Equatable
( ==
)).
Anda bisa filter
menggunakan array dengan penutup:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
Dan Anda dapat menghitung array:
filtered.count // <= returns 1
Jadi, Anda dapat menentukan apakah array menyertakan elemen Anda dengan menggabungkan ini:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
Jika Anda ingin menemukan posisi itu, saya tidak melihat cara yang mewah, tetapi Anda pasti bisa melakukannya seperti ini:
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
}
}
EDIT
Sementara kita melakukannya, untuk latihan yang menyenangkan, mari kita lanjutkan Array
untuk memiliki find
metode:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
Sekarang kita bisa melakukan ini:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
Array
untuk memiliki find
metode yang melakukan apa yang Anda inginkan. Saya belum tahu apakah ini praktik yang baik, tetapi ini adalah eksperimen yang rapi.
enumerate
sehingga tidak berlaku lagi, tetapi Anda benar.
func firstIndex(of element: Element) -> Int?
var alphabets = ["A", "B", "E", "D"]
Contoh 1
let index = alphabets.firstIndex(where: {$0 == "A"})
Contoh2
if let i = alphabets.firstIndex(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
Meskipun indexOf()
bekerja dengan sempurna, itu hanya mengembalikan satu indeks.
Saya mencari cara yang elegan untuk mendapatkan berbagai indeks untuk elemen yang memenuhi beberapa syarat.
Inilah cara melakukannya:
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)
Untuk kelas khusus, Anda perlu menerapkan protokol Setara.
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)
Pembaruan untuk Swift 2:
sequence.contains (elemen) : Mengembalikan nilai true jika urutan yang diberikan (seperti array) berisi elemen yang ditentukan.
Cepat 1:
Jika Anda mencari hanya untuk memeriksa apakah suatu elemen terkandung di dalam array, yaitu, dapatkan indikator boolean, gunakan contains(sequence, element)
alih-alih find(array, element)
:
berisi (urutan, elemen) : Mengembalikan nilai true jika urutan yang diberikan (seperti array) berisi elemen yang ditentukan.
Lihat contoh di bawah ini:
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.
}
dalam Swift 4.2
.index (di mana :) diubah menjadi .firstIndex (di mana :)
array.firstIndex(where: {$0 == "person1"})
Swift 4. Jika array Anda mengandung elemen tipe [String: AnyObject]. Jadi untuk menemukan indeks elemen gunakan kode di bawah ini
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)
Atau Jika Anda ingin menemukan indeks berdasarkan kunci dari Kamus. Di sini array berisi Objects of Model class dan saya mencocokkan properti id.
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
Cepat 2.1
var array = ["0","1","2","3"]
if let index = array.indexOf("1") {
array.removeAtIndex(index)
}
print(array) // ["0","2","3"]
Cepat 3
var array = ["0","1","2","3"]
if let index = array.index(of: "1") {
array.remove(at: index)
}
array.remove(at: 1)
let array
? Penggunaan self
dipertanyakan juga.
Di Swift 4 , jika Anda melintasi array DataModel Anda, pastikan model data Anda sesuai dengan Protokol yang Dapat Diterapkan, mengimplementasikan metode lhs = rhs, dan hanya dengan demikian Anda dapat menggunakan ".index (of". Misalnya
class Photo : Equatable{
var imageURL: URL?
init(imageURL: URL){
self.imageURL = imageURL
}
static func == (lhs: Photo, rhs: Photo) -> Bool{
return lhs.imageURL == rhs.imageURL
}
}
Lalu,
let index = self.photos.index(of: aPhoto)
Dalam Swift 2 (dengan Xcode 7), Array
sertakan indexOf
metode yang disediakan oleh CollectionType
protokol. (Sebenarnya, dua indexOf
metode — satu yang menggunakan persamaan untuk mencocokkan suatu argumen, dan yang lainnya menggunakan penutupan).
Sebelum Swift 2, tidak ada cara untuk jenis generik seperti koleksi untuk menyediakan metode untuk jenis beton yang berasal dari mereka (seperti array). Jadi, di Swift 1.x, "indeks" adalah fungsi global ... Dan namanya juga diganti, jadi di Swift 1.x, fungsi global itu disebut find
.
Mungkin juga (tetapi tidak perlu) menggunakan indexOfObject
metode ini dari NSArray
... atau metode pencarian lain yang lebih canggih dari Foundation yang tidak memiliki padanan dalam pustaka standar Swift. Hanya import Foundation
(atau modul lain yang mengimpor Yayasan secara transitif), sampaikan Array
ke NSArray
, dan Anda dapat menggunakan banyak metode pencarian NSArray
.
Salah satu solusi ini bekerja untuk saya
Ini solusi yang saya miliki untuk Swift 4:
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
})
Anda juga dapat menggunakan dolar perpustakaan fungsional untuk melakukan indexOf pada array seperti http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Jika Anda masih bekerja di Swift 1.x
lalu coba,
let testArray = ["A","B","C"]
let indexOfA = find(testArray, "A")
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
Untuk SWIFT 3 Anda dapat menggunakan fungsi sederhana
func find(objecToFind: String?) -> Int? {
for i in 0...arrayName.count {
if arrayName[i] == objectToFind {
return i
}
}
return nil
}
Ini akan memberikan posisi angka, sehingga Anda dapat menggunakan suka
arrayName.remove(at: (find(objecToFind))!)
Semoga bermanfaat
SWIFT 4
Katakanlah Anda ingin menyimpan nomor dari array bernama cardButtons ke cardNumber, Anda dapat melakukannya dengan cara ini:
let cardNumber = cardButtons.index(of: sender)
pengirim adalah nama tombol Anda
Di Swift 4/5, gunakan "firstIndex" untuk menemukan indeks.
let index = array.firstIndex{$0 == value}
Jika seseorang memiliki masalah ini
Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'
hanya lakukan ini
extension Int {
var toInt: Int {
return self
}
}
kemudian
guard let finalIndex = index?.toInt else {
return false
}
Untuk (>= swift 4.0)
Ini agak sangat sederhana. Pertimbangkan Array
objek berikut .
var names: [String] = ["jack", "rose", "jill"]
Untuk mendapatkan indeks elemen rose
, yang harus Anda lakukan adalah:
names.index(of: "rose") // returns 1
catatan:
Array.index(of:)
mengembalikan sebuah Optional<Int>
.
nil
menyiratkan bahwa elemen tidak ada dalam array.
Anda mungkin ingin membuka paksa nilai yang dikembalikan atau menggunakan if-let
untuk menyiasati opsional.