如何在Swift中查找列表项的索引?
我正在尝试通过search列表来查找项目索引。 有人知道如何做到这一点?
我看到有list.StartIndex和list.EndIndex埠我想要的东西像python的list.index(“文本”)
由于swift在某些方面比面向对象(而数组是结构体,而不是对象)function更强大,所以使用函数“find”对数组进行操作,该数组返回一个可选值,因此准备处理一个零值:
let arr:Array = ["a","b","c"] find(arr, "c")! // 2 find(arr, "d") // nil
Swift 2.0更新:
Swift 2.0不再支持旧的find
函数!
使用Swift 2.0, Array
可以使用在CollectionType
的扩展中定义的函数(该Array
实现)来查找元素的索引:
let arr = ["a","b","c"] let indexOfA = arr.indexOf("a") // 0 let indexOfB = arr.indexOf("b") // 1 let indexOfD = arr.indexOf("d") // nil
另外,查找数组中的第一个元素来实现一个谓词是由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
请注意,这两个函数返回可选值,如前所述。
更新Swift 3.0:
请注意indexOf的语法已更改。 对于符合Equatable
项目,您可以使用:
let indexOfA = arr.index(of: "a")
该方法的详细文档可以在https://developer.apple.com/reference/swift/array/1689674-index
对于不符合Equatable
数组项,您需要使用index(where:)
:
let index = cells.index(where: { (item) -> Bool in item.foo == 42 // test if this is the item you're looking for })
我认为值得一提的是,对于引用types( class
),您可能需要执行标识比较,在这种情况下,您只需要在谓词闭包中使用===
标识运算符:
Swift 3 / Swift 4:
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.index{$0 === person1} // 0 let indexOfPerson2 = people.index{$0 === person2} // 1 let indexOfPerson3 = people.index{$0 === person3} // 2 let indexOfPerson4 = people.index{$0 === person4} // nil
请注意,上面的语法使用了尾随闭包语法,相当于:
let indexOfPerson1 = people.index(where: {$0 === person1})
Swift 2 – index
函数语法曾经是:
let indexOfPerson1 = people.indexOf{$0 === person1}
*请注意paulbailey关于实现Equatable
class
types的相关和有用的评论 ,您需要考虑是否应该使用===
( 身份运算符)或==
( 相等运算符)进行比较。 如果你决定使用==
匹配,那么你可以简单地使用别人build议的方法( people.index(of: person1)
)。
你可以使用闭包filter
一个数组:
var myList = [1, 2, 3, 4] var filtered = myList.filter { $0 == 3 } // <= returns [3]
你可以计算一个数组:
filtered.count // <= returns 1
所以你可以通过结合这些来确定一个数组是否包含你的元素:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
如果你想find位置,我不会看到奇特的方式,但你当然可以这样做:
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 } }
编辑
当我们在这里,为了一个有趣的练习让我们扩展Array
有一个find
方法:
extension Array { func find(includedElement: T -> Bool) -> Int? { for (idx, element) in enumerate(self) { if includedElement(element) { return idx } } return nil } }
现在我们可以做到这一点:
myList.find { $0 == 3 } // returns the index position of 3 or nil if not found
虽然indexOf()
完美地工作, 它只返回一个索引。
我正在寻找一个优雅的方式来获取满足某些条件的元素索引数组。
这是如何做到的:
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)
对于自定义类,您需要实现Equatable协议。
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)
Swift 2更新:
sequence.contains(element) :如果给定序列(如数组)包含指定的元素,则返回true。
Swift 1:
如果你只是想检查一个元素是否包含在一个数组中,也就是说,只是得到一个布尔指标,使用contains(sequence, element)
而不是find(array, element)
:
contains(sequence,element) :如果给定序列(如数组)包含指定的元素,则返回true。
看下面的例子:
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. }
在Swift 2中(目前在Xcode 7testing版中), Array
包含一个由CollectionType
协议提供的indexOf
方法。 (实际上,两个indexOf
方法 – 一个使用平等来匹配一个参数,另一个使用闭包。)
在Swift 2之前,没有像集合这样的genericstypes为从它们派生的具体types(如数组)提供方法。 因此,在Swift 1.x中,“index of”是一个全局函数…并且它也被重命名,所以在Swift 1.x中,全局函数被称为find
。
也可以(但不是必须)使用NSArray
的indexOfObject
方法…或者来自Foundation的其他更复杂的search方法,它们在Swift标准库中没有等价的方法。 只需import Foundation
(或者可传递导入Foundation的另一个模块),将Array
为NSArray
,并且可以在NSArray
上使用多种search方法。
你也可以使用函数库Dollar来做一个indexOf,就像这样一个数组http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2) => 1
如果你还在Swift 1.x中工作
然后尝试,
let testArray = ["A","B","C"] let indexOfA = find(testArray, "A") let indexOfB = find(testArray, "B") let indexOfC = find(testArray, "C")
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)
对于SWIFT 3,您可以使用一个简单的function
func find(objecToFind: String?) -> Int? { for i in 0...arrayName.count { if arrayName[i] == objectToFind { return i } } return nil }
这会给号码的位置,所以你可以使用像
arrayName.remove(at: (find(objecToFind))!)
希望有用
在Swift 4中,如果遍历DataModel数组,请确保您的数据模型符合Equatable协议,执行lhs = rhs方法,然后才能使用“.index(of”)。
class Photo : Equatable{ var imageURL: URL? init(imageURL: URL){ self.imageURL = imageURL } static func == (lhs: Photo, rhs: Photo) -> Bool{ return lhs.imageURL == rhs.imageURL } }
接着,
let index = self.photos.index(of: aPhoto)
斯威夫特4
func index(of element: Element) -> Int?
例
var alphabets = ["A", "B", "E", "D"] if let i = alphabets.index(of: "E") { alphabets[i] = "C" // i is the index } print(alphabets) // Prints "["A", "B", "C", "D"]"