Swift访问由`NSIndexPath`指定的嵌套数组元素

时间:2016-07-22 18:30:23

标签: swift indexing

如果我有这样的嵌套数组:

array[0].children[0].children[0].children[2]

如何访问其中一个嵌套元素?我知道存在NSIndexPath类型来表示嵌套数组的索引路径,但是如何访问给定NSIndexPath指定的元素?

2 个答案:

答案 0 :(得分:0)

我会尝试一个递归函数。但是,由于您不知道树中的级别,您可以尝试搜索特定路径等内容。

我们假设您的节点类是这样的:

class Node<T> {
    var data: T
    var children: Array<Node<T>>?

    init(data: T, children: Array<Node<T>>?) {
        self.data = data
        self.children = children
    }
}

你可以制作这样的函数:

func getNChildren<T>(head: Array<Node<T>>, path: Array<Int>) -> Node<T>? {
    var localPath = path
    // Get the first path and remove it from the array
    let currentPath = localPath.removeFirst()

    if head.indices.contains(currentPath) {
        if localPath.isEmpty {
            // If there's no more in the path, return current element
            return head[currentPath]
        } else {
            if head[currentPath].children != nil {
                // We go looking for children
                return getNChildren(head[currentPath].children!, path: localPath)
            } else {
                // There are no more children, but there are more elements in path, so that level doesn't exist
                return nil
            }
        }

    } else {
        return nil
    }
}

此函数在路径中获取元素(如果存在),否则返回nil(以避免在查找非现有索引时崩溃)。

你可以这样调用这个函数:

let elementAt = getNChildren(tree, path: [0, 0, 0, 2])

let elementAt = getNChildren(tree, path: [0, 1, 2, 3, 5, 8, 13, 2, 1, 3, 4, 0, 3])

我知道这不是最好的方法,但可能有用。

  

更新:

要将数据添加到节点,您必须这样做:

let root = Node(data: 0, children: nil)
let child1 = Node(data: 1, children: nil)
let child2 = Node(data: 1, children: nil)
root.children = [child1, child2]
let arr = [root]

当然,您可以将任何数据类型用作data,这就是Node类被标记为通用<T>的原因。

如果你感觉更舒服,你可以创建一个递归插入子节点的函数。

答案 1 :(得分:-2)

最后,我找到了找到嵌套数组元素的最简单方法:

通过使用KeyPath定位内部数组,如下所示:

class BookIndex: NSObject {
  var title = ""
  var children = [BookIndex]()
}
var root = BookIndex()

如果我有3个这样的孩子,我可以在“孩子”里面设置价值:

root.setValue([BookIndex()], forKeyPath: "children.children.chlidren")

或者我可以这样找到它:

root.valueforKeyPath("children.children.chlidren")

由于“keyPath”是一个String,你可以根据需要在没有限制的情况下在循环内生成路径!