Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 快速访问由`nsindepath指定的嵌套数组元素`_Swift_Indexing - Fatal编程技术网

Swift 快速访问由`nsindepath指定的嵌套数组元素`

Swift 快速访问由`nsindepath指定的嵌套数组元素`,swift,indexing,Swift,Indexing,如果我有这样的嵌套数组: array[0].children[0].children[0].children[2] class Node<T> { var data: T var children: Array<Node<T>>? init(data: T, children: Array<Node<T>>?) { self.data = data self.children

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

array[0].children[0].children[0].children[2]
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
    }
}
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])
class BookIndex: NSObject {
  var title = ""
  var children = [BookIndex]()
}
var root = BookIndex()
root.setValue([BookIndex()], forKeyPath: "children.children.chlidren")
root.valueforKeyPath("children.children.chlidren")

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

我会尝试使用递归函数。但是,由于您不知道树中的级别,因此可以尝试搜索特定路径之类的方法

假设您的节点类如下所示:

array[0].children[0].children[0].children[2]
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
    }
}
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])
class BookIndex: NSObject {
  var title = ""
  var children = [BookIndex]()
}
var root = BookIndex()
root.setValue([BookIndex()], forKeyPath: "children.children.chlidren")
root.valueforKeyPath("children.children.chlidren")
我知道这不是最好的方法,但也许会有用

更新:

要向节点添加数据,必须执行以下操作:

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]
当然,您可以使用任何数据类型作为数据,这就是Node类被标记为泛型的原因


如果您觉得这样做更方便,您可以创建一个函数来递归地将子元素插入节点。

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

使用KeyPath可以定位阵列内部,如下所示:

array[0].children[0].children[0].children[2]
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
    }
}
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])
class BookIndex: NSObject {
  var title = ""
  var children = [BookIndex]()
}
var root = BookIndex()
root.setValue([BookIndex()], forKeyPath: "children.children.chlidren")
root.valueforKeyPath("children.children.chlidren")
如果我有3个这样的子项,我可以在子项中设置值:

array[0].children[0].children[0].children[2]
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
    }
}
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])
class BookIndex: NSObject {
  var title = ""
  var children = [BookIndex]()
}
var root = BookIndex()
root.setValue([BookIndex()], forKeyPath: "children.children.chlidren")
root.valueforKeyPath("children.children.chlidren")
或者我可以这样定位它:

array[0].children[0].children[0].children[2]
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
    }
}
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])
class BookIndex: NSObject {
  var title = ""
  var children = [BookIndex]()
}
var root = BookIndex()
root.setValue([BookIndex()], forKeyPath: "children.children.chlidren")
root.valueforKeyPath("children.children.chlidren")

因为keyPath是一个字符串,所以您可以根据需要在循环中生成路径,没有任何限制

您是否正在寻找数组[0]。children[0]。children[0]。children[2]的较短实现,比如array0.0.0.2之类?问题不在实现中,而是在使用短数字语法定位该数组时,如果我假设您的问题正确,您应该能够调用数组[0][0][0][2],那么请出错!此外,我需要一些我可以使用,如果数组有30个数组,例如!!NSIndexPath是一个很好的解决方案,但我不知道如何使用它。@user2713544我已经更新了我的答案,请再次检查。太好了!!请再说一件事:我可以用另一个func以同样的方式编辑数据吗:比如:setNChildrentree,path:[0,0,7]=当然!但您必须将数据作为参数传递:setNChildrentree,path:[0,0,7],data:something我尝试了以下方法:getnChildrenar,path:[0,0,0],data:BookIndex,其中BookIndex是我的数据类,但我收到了以下消息:调用中有额外的参数“data”!是,因为您正在调用get函数,而不是新的set函数。这将不起作用,因为BookIndex.children是BookIndex的数组,所以当您使用字符串作为路径键时,您没有指示要访问哪个数组索引。