本文翻译自:How to find index of list item in Swift?
I am trying to find an item index
by searching a list
. 我试图通过搜索list
来查找item index
。 Does anybody know how to do that? 有人知道该怎么做吗?
I see there is list.StartIndex
and list.EndIndex
but I want something like python's list.index("text")
. 我看到有list.StartIndex
和list.EndIndex
但是我想要类似python的list.index("text")
。
参考:https://stackoom.com/question/1cp0G/如何在Swift中找到列表项的索引
In Swift 2 (with Xcode 7), Array
includes an indexOf
method provided by the CollectionType
protocol. 在Swift 2(使用Xcode 7)中, Array
包括CollectionType
协议提供的indexOf
方法。 (Actually, two indexOf
methods—one that uses equality to match an argument, and another that uses a closure.) (实际上,有两个indexOf
方法-一个使用相等性来匹配参数, 另一个使用闭包。)
Prior to Swift 2, there wasn't a way for generic types like collections to provide methods for the concrete types derived from them (like arrays). 在Swift 2之前,还没有一种方法可以让通用类型(如集合)提供从其派生的具体类型(如数组)的方法。 So, in Swift 1.x, "index of" is a global function... And it got renamed, too, so in Swift 1.x, that global function is called find
. 因此,在Swift 1.x中,“ index of”是一个全局函数...并且它也被重命名,因此在Swift 1.x中,该全局函数称为find
。
It's also possible (but not necessary) to use the indexOfObject
method from NSArray
... or any of the other, more sophisticated search meth dis from Foundation that don't have equivalents in the Swift standard library. 也可以(但不是必须)使用NSArray
的indexOfObject
方法...或Foundation中其他任何更复杂的搜索方法, indexOfObject
方法在Swift标准库中都没有等效项。 Just import Foundation
(or another module that transitively imports Foundation), cast your Array
to NSArray
, and you can use the many search methods on NSArray
. 只需import Foundation
(或其他可过渡导入Foundation的模块),将Array
为NSArray
,就可以在NSArray
上使用许多搜索方法。
You can filter
an array with a closure: 您可以使用闭包来filter
数组:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
And you can count an array: 您可以计算一个数组:
filtered.count // <= returns 1
So you can determine if an array includes your element by combining these: 所以,你可以决定是否数组包括通过组合这些你的元素:
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
If you want to find the position, I don't see fancy way, but you can certainly do it like this: 如果您想找到职位,我看不到花哨的方法,但是您当然可以这样:
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 编辑
While we're at it, for a fun exercise let's extend Array
to have a find
method: 在进行此操作时,为了有趣的练习,我们将Array
扩展为具有find
方法:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
Now we can do this: 现在我们可以这样做:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
As swift is in some regards more functional than object-oriented (and Arrays are structs, not objects), use the function "find" to operate on the array, which returns an optional value, so be prepared to handle a nil value: 由于Swift在某些方面比面向对象的功能更强大(并且Array是结构,而不是对象),因此请使用函数“ find”对数组进行操作,该数组将返回一个可选值,因此请准备处理nil值:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Update for Swift 2.0: Swift 2.0更新:
The old find
function is not supported any more with Swift 2.0! Swift 2.0不再支持旧的find
函数!
With Swift 2.0, Array
gains the ability to find the index of an element using a function defined in an extension of CollectionType
(which Array
implements): 在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
Additionally, finding the first element in an array fulfilling a predicate is supported by another extension of CollectionType
: 另外, 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
Note that these two functions return optional values, as find
did before. 请注意,这两个函数返回可选值,就像之前的find
一样。
Update for Swift 3.0: Swift 3.0更新:
Note the syntax of indexOf has changed. 注意indexOf的语法已更改。 For items conforming to Equatable
you can use: 对于符合Equatable
物品,您可以使用:
let indexOfA = arr.index(of: "a")
A detailed documentation of the method can be found at https://developer.apple.com/reference/swift/array/1689674-index 有关该方法的详细文档,请参见https://developer.apple.com/reference/swift/array/1689674-index
For array items that don't conform to Equatable
you'll need to use index(where:)
: 对于不符合Equatable
数组项,您需要使用index(where:)
:
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you're looking for
})
Update for Swift 4.2: Swift 4.2更新:
With Swift 4.2, index
is no longer used but is separated into firstIndex
and lastIndex
for better clarification. 在Swift 4.2中,不再使用index
而是将其分为firstIndex
和lastIndex
以便更好地进行说明。 So depending on whether you are looking for the first or last index of the item: 因此,根据您要查找的项目的第一个还是最后一个索引:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
You can also use the functional library Dollar to do an indexOf on an array as such http://www.dollarswift.org/#indexof-indexof 您还可以使用功能库Dollar在数组上执行indexOf,例如http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
Update for Swift 2: Swift 2更新:
sequence.contains(element) : Returns true if a given sequence (such as an array) contains the specified element. sequence.contains(element) :如果给定序列(例如数组)包含指定的元素,则返回true。
Swift 1: 斯威夫特1:
If you're looking just to check if an element is contained inside an array, that is, just get a boolean indicator, use contains(sequence, element)
instead of find(array, element)
: 如果您只是在检查数组中是否包含元素,即仅获取布尔值指示符,请使用contains(sequence, element)
而不是find(array, element)
:
contains(sequence, element) : Returns true if a given sequence (such as an array) contains the specified element. contains(sequence,element) :如果给定序列(例如数组)包含指定的元素,则返回true。
See example below: 请参见下面的示例:
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.
}