我希望能够在这些对象的数组中找到并更新自定义对象.挑战在于,自定义对象也可以是该对象的子对象.

自定义对象如下所示:

class CustomObject: NSObject {
    var id: String?
    var title: String?
    var childObjects: [CustomObject]?
}

我希望能够创建一个用特定ID覆盖自定义对象的函数,如下所示:

 var allCustomObjects: [CustomObject]?
    
 func updateCustomObject(withId id: String, newCustomObject: CustomObject) {
        
     var updatedAllCustomObjects = allCustomObjects
        
     // ...
     // find and update the specific custom object with the id
     // ...
        
     allCustomObjects = updatedAllCustomObjects
 }

我认识到,对于Swift和其他语言中的多维数组/目录,这肯定是一个非常正常的问题.请让我知道这个问题的正常做法.

推荐答案

与大多数与树有关的事情一样,递归也会有所帮助.您可以添加一个额外的参数,指示当前正在使用的CustomObject个数组,并返回一个Bool,指示是否找到了ID,以便进行短路.

@discardableResult
func updateCustomObject(withId id: String, in objectsOrNil: inout [CustomObject]?, newCustomObject: CustomObject) -> Bool {
    guard let objects = objectsOrNil else { return false }
    if let index = objects.firstIndex(where: { $0.id == id }) {
        // base case: if we can find the ID directly in the array passed in
        objectsOrNil?[index] = newCustomObject
        return true
    } else { 
        // recursive case: we need to do the same thing for the children of
        // each of the objects in the array
        for obj in objects {
            // if an update is successful, we can end the loop there!
            if updateCustomObject(withId: id, in: &obj.childObjects, newCustomObject: newCustomObject) {
                return true
            }
        }
        return false
        // technically I think you can also replace the loop with a call to "contains":
        // return objects.contains(where: { 
        //     updateCustomObject(withId: id, in: &$0.childObjects, newCustomObject: newCustomObject) 
        //  })
        // but I don't like doing that because updateCustomObject has side effects
    }
}

你可以这样称呼它,in:参数是allCustomObjects.

updateCustomObject(withId: "...", in: &allCustomObjects, newCustomObject: ...)

Swift相关问答推荐

显示第二个操作紧接在另一个操作后的工作表在SwiftUI中不起作用

在`NavigationStack`中使用`SafeAreaInset`修饰符时出现SwiftUI异常行为

将`@Environment`值赋给`Binding`参数

按下一步后无法让文本字段切换焦点

为什么枚举上的.allCases.forEach不是循环(继续和中断不起作用)?

Swift 扩展:通过方法重载增强现有类

在 Swift 5.7 中使用协议作为类型时什么时候需要写 `any`

如何延迟 swift 属性 didSet 使其每秒只触发一次

UUID 哈希值是不确定的吗?

在 Swift 中为(递归)扩展提供默认实例参数

将基于MyProtocol的泛型函数的参数更改为使用存在的any MyProtocol或some MyProtocol是否会受到惩罚?

试图同时实现两个混合过渡

如何以快速 Select 器菜单样式调整图像大小

在 xcode 13 中的构建之间保持可访问性权限

在 Xcode 中自动实现 Swift 协议方法

在 Swift 框架中加载资源(例如故事板)

在 Swift for iOS 中沿圆形路径绘制文本

UILabel 文本不换行

类型myViewController不符合 Swift 中的协议 UIPIckerDataSource

保持窗口始终在顶部?