Swift - 如何根据条件更改多级 JSON 结构单元素值

Swift - How to Change Multi-Level JSON Struct Single Element Value on Condition

我有多层结构,可以将复杂的 JSON 数据转换为结构。我正在努力的是根据条件更改 dataStruct.group.point.presentValue 元素值。

var dataStruct : DataStruct = load("jsonfile.json")

 struct DataStruct : Codable {
    let name: String
    var group: [groupData]
}

struct groupData: Codable, Hashable {
    let id, name : String
    var point : [pointInfo]

}

struct pointInfo : Codable, Hashable {
    let id : String
    let address : address
    let name : String
    var presentValue : String
}

struct address: Codable, Hashable {
    let index: String
    let type: String
}

我尝试了以下映射函数,但编译器抱怨说 ForEach 中的组是 'let' 常量。 基本上,该函数应该将 Struct 中的 address.index 字段与传递的 pointNo 变量进行比较,一旦找到(唯一), point.presentValue 更改为新值。

实现这个的正确方法是什么?

   func updatePresentValue(pointNo : String) {
        
        dataStruct.group.forEach { Group in
            Group.point = Group.point.map { point -> pointInfo in

                var p = point
                if point.address.index == pointNo {
                    p.presentValue = "New value"
                    return p
                }
                else { return p }
            }
        }
    }

基本上有两种方法。

  • 通过将对象分配给变量来提取对象,修改它们并将它们重新分配到它们在 dataStruct 中的位置。

  • Enumerate 数组并就地修改对象。

这是第二种方式的例子

func updatePresentValue(pointNo : String) {
    for (groupIndex, group) in dataStruct.group.enumerated() {
        for (pointIndex, point) in group.point.enumerated() {
            if point.address.index == pointNo {
                dataStruct.group[groupIndex].point[pointIndex].presentValue = "New value"
            }
        }
    }
 }

处理多级结构时会变得更加复杂,但这里有一种方法,我们首先枚举 group,这样我们就可以在每次迭代中同时获得对象和对象的索引,这样我们就可以更新 group 数组时使用此索引。使用 point

的可变副本更新内部结构
for (index, group) in dataStruct.group.enumerated() {
    if group.point.contains(where: { [=10=].address.index == pointNo }) {
        var copy = group
        copy.point = group.point.reduce(into: []) {
            if .address.index == pointNo {
                var pointCopy = 
                pointCopy.presentValue = "new value"
                [=10=].append(pointCopy)
            } else {
                [=10=].append()
            }
        }
        dataStruct.group[index] = copy
    }
}