How to find the index of an item in a multidimensional array swiftily?

六月ゝ 毕业季﹏ 提交于 2020-01-01 02:41:25

问题


Let's say I have this array:

let a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Now I want something like this:

public func indicesOf(x: Int, array: [[Int]]) -> (Int, Int) {
    ...
}

so that I can call it like this:

indicesOf(7, array: a) // returns (2, 0)

Of course, I can use:

for i in 0..<array.count {
    for j in 0..<array[i].count {
        if array[i][j] == x {
            return (i, j)
        }
    }
}

But that is not even close to swifty!

I want a way to do this which is swifty. I think maybe I can use reduce or map?


回答1:


You can simplify your code slightly with enumerate() and indexOf(). Also the function should return an optional tuple because the element might not be present in the "matrix". Finally, you can make it generic:

func indicesOf<T: Equatable>(x: T, array: [[T]]) -> (Int, Int)? {
    for (i, row) in array.enumerate() {
        if let j = row.indexOf(x) {
            return (i, j)
        }
    }
    return nil
}

You can also make it an extension for a nested Array of Equatable elements:

extension Array where Element : CollectionType,
    Element.Generator.Element : Equatable, Element.Index == Int {
    func indicesOf(x: Element.Generator.Element) -> (Int, Int)? {
        for (i, row) in self.enumerate() {
            if let j = row.indexOf(x) {
                return (i, j)
            }
        }
        return nil
    }
}

if let (i, j) = a.indicesOf(7) {
    print(i, j)
}

Swift 3:

extension Array where Element : Collection,
    Element.Iterator.Element : Equatable, Element.Index == Int {

    func indices(of x: Element.Iterator.Element) -> (Int, Int)? {
        for (i, row) in self.enumerated() {
            if let j = row.index(of: x) {
                return (i, j)
            }
        }
        return nil
    }
}



回答2:


Version accepting a closure, similar to index(where:), so there it is usable on the array of any elements, not only Equatable

extension Array where Element : Collection, Element.Index == Int {
  func indices(where predicate: (Element.Iterator.Element) -> Bool) -> (Int, Int)? {
    for (i, row) in self.enumerated() {
      if let j = row.index(where: predicate) {
        return (i, j)
      }
    }
    return nil
  }
}

Use like this:

let testArray = [[1,2,3], [4,5,6], [7,8]]

let testNumber = 6

print(testArray.indices(of: testNumber))
print(testArray.indices{$0 == testNumber})

Optional((1, 2))
Optional((1, 2))

Also, it can be used with IndexPath:

extension Array where Element : Collection, Element.Index == Int {
  func indexPath(where predicate: (Element.Iterator.Element) -> Bool) -> IndexPath? {
    for (i, row) in self.enumerated() {
      if let j = row.index(where: predicate) {
        return IndexPath(indexes: [i, j])
      }
    }
    return nil
  }
}


来源:https://stackoverflow.com/questions/37314322/how-to-find-the-index-of-an-item-in-a-multidimensional-array-swiftily

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!