How to find index of list item in Swift?

2018-12-31 09:31发布

I am trying to find an item index by searching a list. 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").

标签: arrays swift
17条回答
牵手、夕阳
2楼-- · 2018-12-31 09:58

While indexOf() works perfectly, it only returns one index.

I was looking for an elegant way to get an array of indexes for elements which satisfy some condition.

Here is how it can be done:

Swift 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)
查看更多
一个人的天荒地老
3楼-- · 2018-12-31 09:58

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)
查看更多
妖精总统
4楼-- · 2018-12-31 10:03

If you are still working in Swift 1.x

then try,

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

let indexOfA = find(testArray, "A") 
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
查看更多
姐姐魅力值爆表
5楼-- · 2018-12-31 10:04

In Swift 4, if you are traversing through your DataModel array, make sure your data model conforms to Equatable Protocol , implement the lhs=rhs method , and only then you can use ".index(of" . For example

class Photo : Equatable{
    var imageURL: URL?
    init(imageURL: URL){
        self.imageURL = imageURL
    }

    static func == (lhs: Photo, rhs: Photo) -> Bool{
        return lhs.imageURL == rhs.imageURL
    }
}

And then,

let index = self.photos.index(of: aPhoto)
查看更多
看淡一切
6楼-- · 2018-12-31 10:06

In Swift 2 (with Xcode 7), Array includes an indexOf method provided by the CollectionType protocol. (Actually, two indexOf methods—one that uses equality to match an argument, and another that uses a closure.)

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

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

查看更多
怪性笑人.
7楼-- · 2018-12-31 10:08

You can filter an array with a closure:

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:

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
查看更多
登录 后发表回答