我正在尝试通过搜索item index来找到list。有人知道该怎么做吗?

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

#1 楼

由于在某些方面Swift的功能比面向对象的功能更强大(并且Array是结构而不是对象),因此请使用函数“ find”对数组进行操作,该数组将返回可选值,因此请准备处理nil值:

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({
let indexOfA = arr.index(of: "a")
> 5}) // 5 let indexOfFirstGreaterThanOneHundred = arr2.indexOf({
let index = cells.index(where: { (item) -> Bool in
  item.foo == 42 // test if this is the item you're looking for
})
> 100}) // nil


请注意,这两个函数返回可选值,就像find以前一样。

Swift 3.0的更新:

请注意indexOf的语法已更改。对于符合Equatable的项目,您可以使用:

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

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


有关该方法的详细文档,请访问https://developer.apple.com/reference/swift/ array / 1689674-index

对于不符合Equatable的数组项,您需要使用index(where:)

q4312078q

更新以下内容Swift 4.2:

在Swift 4.2中,不再使用index,而是将其分成firstIndexlastIndex,以进行更好的说明。因此,取决于您要查找的是项目的第一个索引还是最后一个索引:

q4312078q

评论


您从哪里了解查找功能的?我似乎找不到“ find”的任何文档或任何其他全局函数

–约翰内斯
14年6月13日在17:48

来自OOP世界,我应该如何找到这种自由浮动函数?

–鲁道夫·亚当科维奇
2014年9月11日21:00

他们似乎基本上没有证件。有关列表,请参见Practicalswift.com/2014/06/14/…(但请注意,我没有检查列表是否完整或最新)。

–塞巴斯蒂安·舒斯(Sebastian Schuth)
2014年9月12日14:59

Johannes和@Rudolf-使用Dash.app。这是一个用于浏览文档的OS X应用程序。它具有Swift的语言参考,其中列出了所有自由浮动函数。易于过滤和搜索。没有它就无法生存。

–比约恩
2015年1月17日下午6:25

仅供参考:如果您在自己定义的结构数组上使用indexOf,则您的结构必须符合Equatable协议。

–MLQ
15年7月15日在7:52

#2 楼

tl; dr:

对于类,您可能正在寻找:

 let index = someArray.firstIndex{class === someObject}
 



完整答案:

我认为值得一提的是,对于引用类型(===),您可能想要执行身份比较,在这种情况下,您只需要使用谓词闭包中的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{let indexOfPerson1 = people.firstIndex(where: {index === person1}) === person1} // 0 let indexOfPerson2 = people.firstIndex{indexOf === person2} // 1 let indexOfPerson3 = people.firstIndex{class === person3} // 2 let indexOfPerson4 = people.firstIndex{Equatable === person4} // nil 身份运算符:





Swift 5,Swift 4.2:

 === 


请注意,以上语法使用结尾闭包语法,等效于:

 == 



Swift 4 / Swift 3-以前称为==

Swift 2-the以前称为people.firstIndex(of: person1)的函数


*请注意paulbailey有关实现q4312079q的q4312079q类型的相关且有用的注释,在此需要考虑是否应该比较使用q4312079q(身份运算符)或q4312079q(平等运算符)进行提醒。如果决定使用q4312079q进行匹配,则可以简单地使用其他人建议的方法(q4312079q)。

评论


对于那些想知道.indexOf(x)为什么不起作用的人来说,这是一个有用的帖子-这种解决方案是出乎意料的,但回想起来很明显。

–毛里·马克维兹(Maury Markowitz)
16年2月10日在16:35

非常感谢,但这一点对我来说并不明显。我查看了文档,但我真的不明白为什么在引用类型上使用indexOf时为什么需要断言?感觉indexOf应该已经能够自己处理引用类型。应该知道这是引用类型,而不是值类型。

–克里斯
16 Mar 8 '16 at 13:18



如果Person实现了Equatable协议,则不需要此协议。

–paulbailey
16-3-29在15:26

我收到:二进制运算符'==='不能应用于类型'_'和'Post'的操作数,Post是我的结构...任何想法吗?

– David Seek
16 Dec 21'在17:05

@DavidSeek,结构(和枚举)是值类型,而不是引用类型。仅引用类型(例如类)具有身份比较逻辑(===)。查看有关结构的其他答案(基本上,您只需使用array.index(of:myStruct),确保myStruct的类型符合Equatable(==))。

– Nikolay Suvandzhiev
17-10-6在9:38



#3 楼

您可以filter一个带有闭包的数组:

var myList = [1, 2, 3, 4]
var filtered = myList.filter { 
filtered.count // <= returns 1
== 3 } // <= returns [3]


,您还可以计算一个数组:

myList.filter { 
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
    }
}
== 3 }.count > 0 // <= returns true if the array includes 3


因此,您可以通过组合使用这些元素来确定数组是否包含您的元素:

extension Array {
    func find(includedElement: T -> Bool) -> Int? {
        for (idx, element) in enumerate(self) {
            if includedElement(element) {
                return idx
            }
        }
        return nil
    }
}


如果您想找到位置,我看不到任何奇特的方式,但是您可以肯定是这样的:

myList.find { q4312078q == 3 }
// returns the index position of 3 or nil if not found


编辑

我们正在做一个有趣的练习,让我们将Array扩展为一个find方法:

q4312078q

现在我们可以这样做:

q4312078q

评论


为了好玩,我添加了另一个示例,其中我扩展了内置数组以具有可以执行所需功能的find方法。我还不知道这是否是个好习惯,但这是一个很好的实验。

– gwcoffey
2014年6月4日4:50

只是要指出,您应该按照docs使用++ idx:“除非您需要i ++的特定行为,否则建议在所有情况下都使用++ i和--i,因为它们具有典型的预期效果。修改i并返回结果的行为。”

–登录
2014年6月4日下午5:05

好决定。在您发布此内容时,我正在对其进行修改以使用枚举,因此它不再适用,但是您绝对正确。

– gwcoffey
2014年6月4日在5:07

是的,我记得在进行示例时注意到其中一个例子。现在尝试让自己养成习惯:)

–登录
2014年6月4日在5:10

为了使它在Swift 2 / XCode 7下工作,您需要对其进行如下修改。将(includedElement:T-> Bool)替换为(includedElement:Element-> Bool)并将enumerate(self)更改为self.enumerate

–踏板车
16 Mar 7 '16 at 0:42

#4 楼

Swift 5

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

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


Example1

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


Example2

q4312078q

#5 楼

虽然indexOf()可以正常工作,但它只会返回一个索引。

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

这是可以完成以下操作:

Swift 3:

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

let indexes = array.enumerated().filter {
    
let array = ["apple", "dog", "log"]

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

print(indexes)
.element.contains("og") }.map{q4312078q.offset} print(indexes)


Swift 2:

q4312078q

评论


在子序列上使用此符号时要小心,将其偏移量与索引不同。并非所有集合索引都从零开始。请注意,这仅适用于Equatable元素。 let index = array.indices.filter {array [$ 0] .contains(“ og”)}或使用zip let index = zip(array.indices,array).filter {$ 1.contains(“ og”)} .map( \ .0)

– Leo Dabus
7月17日17:55



#6 楼

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


#7 楼

在Swift 4.2中

.index(where :)更改为.firstIndex(where :)

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


#8 楼

Swift 2的更新:


sequence.contains(element):如果给定序列(例如
数组)包含指定的元素,则返回true。


迅速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.   
}


#9 楼

Swift4。如果您的数组包含[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)


或者如果要基于Dictionary的键来找到索引。这里的数组包含Model类的对象,并且我正在匹配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(q4312078q.store_id) == storeId }! // Array contains models and finding specific one


#10 楼

在Swift 4中,如果要遍历DataModel数组,请确保您的数据模型符合Equatable Protocol,实现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)


#11 楼

只需使用firstIndex方法。

array.firstIndex(where: { q4312078q == searchedItem })


#12 楼

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)


评论


你正在变异一个let数组吗?自我的使用也值得怀疑。

–Chéyo
2015年11月10日在16:37

#13 楼

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

在Swift 2之前,没有一种方法可以像集合那样提供泛型类型从它们派生的具体类型的方法(例如数组)。因此,在Swift 1.x中,“ index of”是一个全局函数...并且它也被重命名,因此在Swift 1.x中,该全局函数称为find

它也是可能(但不是必需)使用来自indexOfObjectNSArray方法或其他来自Foundation的,在Swift标准库中没有等效方法的更复杂的搜索方法。只需import Foundation(或可移植地导入Foundation的另一个模块),将Array转换为NSArray,您就可以在NSArray上使用多种搜索方法。

#14 楼

任何一种解决方案都对我有用

我为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
            q4312078q === tuesday
        })


#15 楼

您还可以使用功能库Dollar在数组上执行indexOf,例如http://www.dollarswift.org/#indexof-indexof

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


#16 楼

如果您仍在使用Swift 1.x

,请尝试,

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

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


#17 楼

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

let index = array.firstIndex{q4312078q == value}


#18 楼

对于SWIFT 3,您可以使用简单的功能

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


这将给出数字位置,因此您可以使用像

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


希望有用

#19 楼

如果有人遇到此问题

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
}


#20 楼

对于(>= 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绕过可选值。


#21 楼

Swift 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
    }
}


#22 楼

SWIFT 4

假设您要将一个名为cardButtons的数组中的数字存储到cardNumber中,则可以这样操作:

let cardNumber = cardButtons.index(of: sender)


发件人是您按钮的名称