2016-05-19 11 views
6

Hãy nói rằng tôi có mảng này:Làm cách nào để tìm chỉ mục của một mục trong một mảng đa chiều nhanh chóng?

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

Bây giờ tôi muốn một cái gì đó như thế này:

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

vì vậy mà tôi có thể gọi nó như thế này:

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

Tất nhiên, tôi có thể sử dụng:

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

Nhưng đó không phải là ngay cả gần swifty!

Tôi muốn có cách để thực hiện điều này nhanh chóng. Tôi nghĩ có lẽ tôi có thể sử dụng reduce hoặc map?

+0

Nó không có ý nghĩa khi sử dụng 'map/filter/reduce' cho trường hợp này bởi vì bạn không cần phải chuyển đổi danh sách thứ gì đó thành danh sách của một điều khác. Bạn chỉ cần làm một số loại kiểm tra bình đẳng giữa các giá trị bằng cách sử dụng 'enumerate()' nếu bạn nghĩ rằng subscript và '.count' trông xấu xí. – ozgur

Trả lời

8

Bạn có thể đơn giản hóa mã của mình một chút với enumerate()indexOf(). Ngoài ra, hàm sẽ trả về một bộ tùy chọn vì phần tử có thể không có trong "ma trận". Cuối cùng, bạn có thể làm cho nó chung chung:

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 
} 

Bạn cũng có thể làm cho nó một phần mở rộng cho một lồng nhau Array của Equatable yếu tố:

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

Cảm ơn bạn! Tôi thực sự không biết rằng 'liệt kê' là _this_ hữu ích cho đến bây giờ! – Sweeper

Các vấn đề liên quan