2016-05-19 99 views
6

比方說,我有這樣的數組:如何快速查找多維數組中項目的索引?

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

現在,我想是這樣的:

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

,這樣我可以這樣調用:

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

當然,我可以使用:

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

但這甚至不太接近swifty!

我想要一個方法來做到這一點很快速。我想也許我可以使用reducemap

+0

它在這種情況下使用'map/filter/reduce'沒有意義,因爲您不需要將某個列表轉換爲列表另一件事。如果你認爲下標和'.count'看起來很醜,你就必須使用'enumerate()'來進行值之間的平等檢查。 – ozgur

回答

8

您可以用enumerate()indexOf()稍微簡化您的代碼。 此外,函數應該返回一個可選的元組,因爲元素 可能不存在於「矩陣」中。最後,你可以把它通用:

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 
} 

你也可以把它嵌套的ArrayEquatable 元素的擴展:

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

斯威夫特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 
    } 
} 
+0

謝謝!我實際上並不知道'enumerate'是_this_有用的,直到現在! – Sweeper