Search code examples
swiftstructmulti-level

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


I have multi-level Struct that converts complex JSON data to a Struct. What I am struggling is to change the dataStruct.group.point.presentValue element value on condition.

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
}

I have tried the following map function, but the compiler complains that the Group in ForEach is 'let' constant. Basically the function is supposed to compare address.index field in the Struct to the passed pointNo variable, and once it has been found (unique), point.presentValue is changed to the new value.

What is the correct way to achieve this?

   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 }
            }
        }
    }

Solution

  • Basically there are two ways.

    • Extract the objects by assigning them to variables, modify them and reassign them to their position in dataStruct.

    • Enumerate the arrays and modify the objects in place.

    This is an example of the second way

    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"
                }
            }
        }
     }