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

时间:2014-06-04 04:10:42

标签: arrays swift

我试图通过搜索列表来查找项目索引。有谁知道怎么做?

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

23 个答案:

答案 0 :(得分:756)

由于swift在某些方面比面向对象更具功能性(并且Arrays是结构体,而不是对象),因此使用函数" 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能够使用扩展名CollectionTypeArray实现)中定义的函数来查找元素的索引:

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

请注意,这两个函数返回可选值,如find之前所做的那样。

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

Swift 4.2的更新:

使用Swift 4.2,index不再使用,但会分为firstIndexlastIndex以便更好地说明。因此,取决于您是否正在寻找项目的第一个或最后一个索引:

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

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

答案 1 :(得分:176)

TL; DR:

对于课程,您可能正在寻找:

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

完整答案:

我认为值得一提的是,使用引用类型(class),您可能希望执行身份比较,在这种情况下,您只需要使用{{谓词闭包中的1}} identity运算符:


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


Swift 4 / Swift 3 - 以前称为let indexOfPerson1 = people.firstIndex(where: {$0 === person1})

的函数

Swift 2 - 以前称为index的函数

*请注意comment关于实施indexOf的{​​{1}}类型的相关且有用的paulbailey,您需要考虑是否应使用{{1}进行比较(身份运算符)或class相等运算符)。如果您决定使用Equatable进行匹配,则只需使用其他人建议的方法(===)。

答案 2 :(得分:80)

你可以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

答案 3 :(得分:24)

Swift 5

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

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

示例1

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

例2

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

答案 4 :(得分:23)

虽然indexOf()完美无缺,只返回一个索引。

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

以下是如何做到的:

斯威夫特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)

答案 5 :(得分:12)

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

答案 6 :(得分:9)

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

答案 7 :(得分:5)

Swift 4.2

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

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

答案 8 :(得分:5)

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

或者如果你想在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")
}

答案 9 :(得分:4)

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

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

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

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

从 Swift 的文档中阅读更多关于这些运算符的内容是值得的。

答案 10 :(得分:4)

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

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

也可以(但不是必须)使用indexOfObject中的NSArray方法......或任何其他更复杂的搜索方法,来自基金会没有等效的Swift标准库。只需import Foundation(或另一个传递基金会的模块),将Array投射到NSArray,您就可以使用NSArray上的多种搜索方法。

答案 11 :(得分:4)

只需使用firstIndex方法。

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

答案 12 :(得分:4)

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

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

答案 13 :(得分:4)

Swift 4 中,如果您遍历DataModel数组,请确保您的数据模型符合Equatable Protocol,实现lhs = rhs方法,然后才能使用“.index”(。 “。例如

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)

答案 14 :(得分:2)

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)

答案 15 :(得分:2)

如果你还在使用Swift 1.x

然后试试,

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

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

答案 16 :(得分:2)

您还可以使用函数库Dollar对数组执行indexOf http://www.dollarswift.org/#indexof-indexof

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

答案 17 :(得分:1)

SWIFT 4

假设您要将一个名为cardButtons的数组中的数字存储到cardNumber中,可以通过以下方式实现:

let cardNumber = cardButtons.index(of: sender)

发件人是您按钮的名称

答案 18 :(得分:1)

万一有人有这个问题

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

jsut为此

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

然后

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

答案 19 :(得分:1)

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

答案 20 :(得分:0)

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

答案 21 :(得分:0)

对于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))!)

希望有用

答案 22 :(得分:0)

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

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