如何在多维数组中快速找到项的索引?

时间:2016-05-19 05:08:34

标签: swift multidimensional-array

假设我有这个数组:

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

2 个答案:

答案 0 :(得分:12)

您可以使用enumerate()indexOf()略微简化代码。 此函数还应返回一个可选元组,因为该元素 可能不会出现在&#34;矩阵&#34;中。最后,你可以使它通用:

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
}

您还可以将其设为Array Equatable的嵌套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) } 的扩展名 元素:

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

斯威夫特3:

 jobs10 = load 'data/hw4/jobs/20140213_descriptions10.csv' using PigStorage(',') as (id:chararray,descr:chararray);
 descrFlat = foreach jobs10 generate id,flatten(TOKENIZE(descr));
 stopwords = load 'data/hw4/stopwords-en.txt' using PigStorage('\n') as (word:chararray);

答案 1 :(得分:5)

接受闭包的版本,类似于index(where:),因此可以在任何元素的数组上使用,而不仅仅是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
  }
}

像这样使用:

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

此外,它可以与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
  }
}