如何获取嵌套数组中项目的路径以便修改数组?

问题描述 投票:0回答:1

我正在将 Core Data 与 CloudKit 结合使用,我想做的是将数据从那里导出到文件中。任何项目都可以有子项目,这意味着子项目可以有子项目,这意味着项目可以嵌套任意数量的级别。我的问题是我不知道如何获取嵌套项目的路径,以便我可以将其子项添加到 itemEntries 数组中。我的另一个问题是,即使我确实有一个名为 pathToItem 的变量,其路径正确,例如 [0][0][0] 我不知道如何使用该变量来更新 itemEntries 数组,因为我假设 itemEntries[pathToItem ] 不行。


    @State private var itemEntries: [ItemEntry] = []
    
    struct ItemEntry: Codable {
        var title: String
        var children: [ItemEntry]
    }
    
    private func populateNestedData(items: [Item], itemsAreNested: Bool = false) {
        for item in items {
            if (!itemsAreNested) {
                itemEntries.append(createItemEntry(item: item))
            }
            else {
              //Here is my problem. The item could be any number of levels nested. How can I get the path to the item so that I can use it to append the child item to the itemEntries array?
                let pathToItem = ?????
              //And even if I did have pathToItem such as [0][0][0] how would I then use that correctly here?
                itemEntries[pathToItem].children.append(createItemEntry(item: item))
            }
            
            if (!item.childrenArray.isEmpty) {
                var children = coreDataController.getChildrenOfItemForExporting(item: item)
                populateNestedData(items: children, itemsAreNested: true)
            }
        }
    }
    
    private func createItemEntry(item: Item) -> ItemEntry {
        return ItemEntry(
            title: item.title ?? "",
            children: []
        )
    }
swift recursion multidimensional-array
1个回答
0
投票

如果我理解正确的话,您正在寻找关键路径。它们代表获取/设置类型属性的“路径”,或数组的索引。

键路径将代表您要附加到的数组。您在每次递归调用中不断附加它,以“更深一层”。最初,它是

\.self
,代表“空”路径。

private func populateNestedData(items: [Item], keyPath: WritableKeyPath<[ItemEntry], [ItemEntry]> = \.self) {
    for item in items {
        itemEntries[keyPath: keyPath].append(createItemEntry(item: item))
        
        if (!item.childrenArray.isEmpty) {
            let children = ...
            populateNestedData(
                items: children,
                // appends the key path representing the children of the item last inserted to itemEntries[keyPath: keyPath]
                keyPath: keyPath.appending(path: \.[itemEntries[keyPath: keyPath].count - 1].children)
            )
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.