如何在Swift中查找列表项的索引?

我试图通过搜索list找到一个item index。有人知道怎么做吗?

我看到有list.StartIndexlist.EndIndex,但我想要类似python的list.index("text")

639331 次浏览

在Swift 2 (Xcode 7)中,Array包含CollectionType协议提供的indexOf方法。(实际上,有两个indexOf方法——一个使用相等来匹配参数,另一个使用闭包。)

在Swift 2之前,泛型类型(如集合)无法为从它们派生的具体类型(如数组)提供方法。所以,在Swift 1中。X, index of是一个全局函数…它也被重新命名了,所以在Swift 1中。x,这个全局函数被称为find

NSArray中使用indexOfObject方法也是可能的(但不是必要的)…或者其他任何来自基金会的更复杂的搜索方法,这些方法在Swift标准库中没有等价物。只要import Foundation(或另一个传递导入Foundation的模块),将你的Array转换为NSArray,你就可以使用NSArray上的许多搜索方法。

你可以用闭包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

如果你想找这个职位,我不认为有什么花哨的方法,但你可以这样做:

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

由于swift在某些方面比面向对象的函数性更强(数组是结构体,而不是对象),所以使用"find"要对数组进行操作,返回一个可选值,所以要准备好处理nil值:

let arr:Array = ["a","b","c"]
find(arr, "c")!              // 2
find(arr, "d")               // nil

使用firstIndexlastIndex -这取决于你是在寻找项目的第一个索引还是最后一个索引:

let arr = ["a","b","c","a"]


let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3

你也可以使用函数库Dollar对数组http://www.dollarswift.org/#indexof-indexof这样的数组执行indexOf

$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1

Swift 2更新:

sequence.contains(元素):如果给定序列(例如

.数组)包含指定的元素

斯威夫特1:

如果你只是检查一个元素是否包含在一个数组中,也就是说,只是得到一个布尔指示符,使用contains(sequence, element)而不是find(array, element):

包含(序列,元素):如果给定序列(例如

.数组)包含指定的元素

请看下面的例子:

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 1.x

然后尝试,

let testArray = ["A","B","C"]


let indexOfA = find(testArray, "A")
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")

tl;博士:

对于课程,你可能会寻找:

let index = someArray.firstIndex{$0 === someObject}

完整的回答:

我认为值得一提的是,对于引用类型(class),你可能想要执行身份比较,在这种情况下,你只需要在谓词闭包中使用===标识操作符:

< br >

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

注意,上面的语法使用了尾随闭包语法,等价于:

let indexOfPerson1 = people.firstIndex(where: {$0 === person1})
< p > < br > Swift 4 / Swift 3 -函数过去被称为index

Swift 2 -该函数过去被称为indexOf

*注意评论 by paulbailey关于实现Equatableclass类型的相关和有用的评论,在这里你需要考虑是否应该使用=== (身份操作符)或== (平等操作符)进行比较。如果你决定使用==进行匹配,那么你可以简单地使用其他人建议的方法(people.firstIndex(of: person1))。

斯威夫特2.1

var array = ["0","1","2","3"]


if let index = array.indexOf("1") {
array.removeAtIndex(index)
}


print(array) // ["0","2","3"]

斯威夫特3

var array = ["0","1","2","3"]


if let index = array.index(of: "1") {
array.remove(at: index)
}
array.remove(at: 1)

对于自定义类,您需要实现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)

虽然indexOf()工作得很好,但它只返回一个索引。

我正在寻找一种优雅的方法来获得满足某些条件的元素的索引数组。

以下是如何做到这一点:

斯威夫特3:

let array = ["apple", "dog", "log"]


let indexes = array.enumerated().filter {
$0.element.contains("og")
}.map{$0.offset}


print(indexes)

斯威夫特2:

let array = ["apple", "dog", "log"]


let indexes = array.enumerate().filter {
$0.element.containsString("og")
}.map{$0.index}


print(indexes)

对于SWIFT 3,您可以使用一个简单的函数

func find(objecToFind: String?) -> Int? {
for i in 0...arrayName.count {
if arrayName[i] == objectToFind {
return i
}
}
return nil
}

这将给出数字的位置,所以你可以用like

arrayName.remove(at: (find(objecToFind))!)

希望对你有用

斯威夫特4中,如果你正在遍历你的DataModel数组,确保你的数据模型符合均衡协议,实现lhs=rhs方法,只有这样你才能使用"。指数(“。例如

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)

斯威夫特5

func firstIndex(of element: Element) -> Int?


var alphabets = ["A", "B", "E", "D"]

例二

let index = alphabets.firstIndex(where: {$0 == "A"})

Example2

if let i = alphabets.firstIndex(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"

斯威夫特4

参考类型:

extension Array where Array.Element: AnyObject {


func index(ofElement element: Element) -> Int? {
for (currentIndex, currentElement) in self.enumerated() {
if currentElement === element {
return currentIndex
}
}
return nil
}
}

斯威夫特4。如果数组包含类型为[String: AnyObject]的元素。因此,要查找元素的索引,请使用下面的代码

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)

或者如果你想找到索引的基础上的关键字从字典。这里数组包含对象的模型类和我匹配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

这些方法对我都适用

这是我对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
})

斯威夫特4

假设你想从名为cardButtons的数组中存储一个数字到cardNumber中,你可以这样做:

let cardNumber = cardButtons.index(of: sender)

Sender是按钮的名称

在Swift 4/5中,使用“firstIndex”查找索引。

let index = array.firstIndex{$0 == value}

斯威夫特4.2

.index(地点:)改为.firstIndex(地点:)

array.firstIndex(where: {$0 == "person1"})

以防有人遇到这种问题

Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'

一定要这么做

extension Int {
var toInt: Int {
return self
}
}

然后

guard let finalIndex = index?.toInt else {
return false
}

对于(>= swift 4.0)

这相当简单。 考虑下面的Array对象
var names: [String] = ["jack", "rose", "jill"]

为了获得元素rose的索引,你所要做的就是:

names.index(of: "rose") // returns 1

注意:

  • Array.index(of:)返回一个Optional<Int>

  • nil表示该元素不在数组中。

  • 你可能想要强制打开返回值或使用if-let来绕过可选。

只需使用firstIndex方法。

array.firstIndex(where: { $0 == searchedItem })

在Swift 4中,可以使用firstIndex方法。使用==相等操作符在数组中通过id查找对象的示例:

let index = array.firstIndex{ $0.id == object.id }
  • 注意,这个解决方案避免了你的代码需要符合公平的协议,因为我们比较的是属性而不是整个对象

另外,关于=====的注意事项,因为到目前为止发布的许多答案在用法上有所不同:

  • ==是相等运算符。它检查值是否相等。
  • ===是标识符。它检查一个类的两个实例是否指向同一个内存。这与相等不同,因为使用相同值独立创建的两个对象使用==被认为是相等的,而不是===,因为它们是不同的对象。()

从Swift的文档中阅读更多关于这些运营商的信息是值得的。