Bir listede
arama yaparak bir öğe dizini
bulmaya çalışıyorum. Bunu nasıl yapacağımı bilen var mı?
Gördüğüm kadarıyla list.StartIndex
ve list.EndIndex
var ama ben python'daki list.index("text")
gibi bir şey istiyorum.
Swift bazı açılardan nesne yönelimli olmaktan çok işlevsel olduğu için (ve Diziler nesne değil yapıdır), dizi üzerinde işlem yapmak için "find" işlevini kullanın, bu işlev isteğe bağlı bir değer döndürür, bu nedenle nil değerini işlemeye hazır olun:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Swift 2.0 için Güncelleme:
*Eski find
fonksiyonu Swift 2.0 ile artık desteklenmiyor!
Swift 2.0 ile Array
, CollectionType
(Array
in uyguladığı) uzantısında tanımlanan bir fonksiyonu kullanarak bir elemanın indeksini bulma yeteneği kazanır:
let arr = ["a","b","c"]
let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil
Ayrıca, bir yüklemi yerine getiren bir dizideki ilk elemanı bulmak CollectionType
ın başka bir uzantısı tarafından desteklenir:
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
Bu iki fonksiyonun daha önce find
fonksiyonunda olduğu gibi isteğe bağlı değerler döndürdüğüne dikkat edin.
Swift 3.0 için Güncelleme:
indexOf sözdiziminin değiştiğine dikkat edin. Equatable
ile uyumlu öğeler için kullanabilirsiniz:
let indexOfA = arr.index(of: "a")
Yöntemin ayrıntılı bir dokümantasyonu https://developer.apple.com/reference/swift/array/1689674-index adresinde bulunabilir.
'Equatable'a uymayan dizi öğeleri için index(where:)
kullanmanız gerekir:
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you're looking for
})
Swift 4.2 için Güncelleme:
Swift 4.2 ile index
artık kullanılmıyor, daha iyi anlaşılması için firstIndex
ve lastIndex
olarak ayrılıyor. Yani öğenin ilk veya son indeksini aramanıza bağlı olarak:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
Bir diziyi bir closure ile filter
edebilirsiniz:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
Ve bir diziyi sayabilirsiniz:
filtered.count // <= returns 1
Böylece bir dizinin sizin elemanınızı içerip içermediğini bunları birleştirerek belirleyebilirsiniz:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
Eğer pozisyonu bulmak istiyorsanız, fantezi bir yol göremiyorum, ama kesinlikle bu şekilde yapabilirsiniz:
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
Hazır başlamışken, eğlenceli bir alıştırma için Array
i bir find
metoduna sahip olacak şekilde genişletelim:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
Şimdi bunu yapabiliriz:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
Swift 2'de (Xcode 7 ile), Array
[CollectionType
][collection] protokolü tarafından sağlanan bir indexOf
yöntemi içerir. (Aslında, biri bir argümanı eşleştirmek için eşitlik kullanan ve diğeri bir kapanış kullanan iki indexOf
yöntemi).
Swift 2'den önce, koleksiyonlar gibi genel türlerin kendilerinden türetilen somut türler (diziler gibi) için yöntemler sağlamasının bir yolu yoktu. Yani, Swift 1.x'de, "index of" global bir fonksiyondur... Ve ismi de değiştirildi, yani Swift 1.x'de bu global fonksiyon find
olarak adlandırılıyor.
Ayrıca NSArray'den
indexOfObjectmetodunu kullanmak da mümkündür (ancak gerekli değildir)... veya Foundation'ın Swift standart kütüphanesinde eşdeğeri olmayan diğer daha sofistike arama metotlarından herhangi birini kullanmak da mümkündür. Sadece
import Foundation(ya da Foundation
ı geçişli olarak içe aktaran başka bir modül), Array
inizi NSArray
e dönüştürün ve NSArray
üzerindeki birçok arama yöntemini kullanabilirsiniz.