34

Is there a method called indexof or something similar?

var array = ["Jason", "Charles", "David"]

indexOf(array, "Jason") // Should return 0
Barnash
  • 2,012
  • 3
  • 19
  • 22

7 Answers7

60

EDIT: As of Swift 3.0, you should use the .index(where:) method instead and follow the change in the Swift 2.0 edit below.

EDIT: As of Swift 2.0, you should use the indexOf method instead. It too returns nil or the first index of its argument.

if let i = array.indexOf("Jason") {
    print("Jason is at index \(i)")
} else {
    print("Jason isn't in the array")
}

Use the find function. It returns either nil (if the value isn't found) or the first index of the value in the array.

if let i = find(array, "Jason") {
    println("Jason is at index \(i)")
} else {
    println("Jason isn't in the array")
}
John Difool
  • 5,572
  • 5
  • 45
  • 80
nathan
  • 5,466
  • 3
  • 27
  • 24
14

In Swift 2.0 (Xcode 7.1b), you can use

if let result = array.indexOf("Jason")

while find(array, "Jason") is deprecated.

green_knight
  • 1,319
  • 14
  • 26
8

I made this function like above, but it return array of indexes

extension Array {
    func indexesOf<T : Equatable>(object:T) -> [Int] {
        var result: [Int] = []
        for (index,obj) in enumerate(self) {
            if obj as T == object {
                result.append(index)
            }
        }
        return result
    }
}

Maybe it will be useful for you

Max MacLeod
  • 26,115
  • 13
  • 104
  • 132
CHiP-love-NY
  • 507
  • 6
  • 14
1

Array can be bridged to an NSArray, so you can use:

array.bridgeToObjectiveC().indexOfObject("Jason")
Ben Gottlieb
  • 85,404
  • 22
  • 176
  • 172
1

An extension of Array can work wonders here. Here's an implementation shared in this StackOverflow answer:

extension Array {
  func find (includedElement: T -> Bool) -> Int? {
    for (idx, element) in enumerate(self) {
      if includedElement(element) {
        return idx
      }
    }
    return nil
  }
}
Community
  • 1
  • 1
aleclarson
  • 18,087
  • 14
  • 64
  • 91
1

You can add an Array Extension that does exactly what you want, i.e:

extension Array {
    func indexOf<T : Equatable>(x:T) -> Int? {
        for i in 0..self.count {
            if self[i] as T == x {
                return i
            }
        }
        return nil
    }
}

Which now lets you use .indexOf() on all Swift arrays, e.g:

["Jason", "Charles", "David"].indexOf("Jason")  //0
mythz
  • 141,670
  • 29
  • 246
  • 390
0

While the response from Max is great, it does not let you find multiple indexes of multiple objects, ie. indexes of the subset of the array. If you need that functionality, extensions are, as always, your best friend

func indexesOfSubset<T : Equatable>(objects : [T]) -> [Int] {

    // Create storage for filtered objectsand results
    var unusedObjects = objects
    var result : [Int] = []

    // Enumerate through all objects in array
    for (index, obj) in enumerate(self) {

        // Enumerate again through all objects that has not been found
        for x in unusedObjects {

            // If we hit match, append result, remove it from usused objects
            if obj as! T == x {
                result.append(index)
                unusedObjects = unusedObjects.filter( { $0 != x } )
                break
            }
        }
    }

    // Get results
    return result
}

Note* : Works on Swift 1.2, if you want compatibility with 1.1, replace as! -> as

Jiri Trecak
  • 5,092
  • 26
  • 37