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 }
}
}
}
CodePudding user response:
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"
}
}
}
}
CodePudding user response:
It gets more complicated when dealing with multilevel structures but here is one way to do it where we first enumerate over group
so we get both the object and the index of the object for each iteration so we can use this index when updating the group
array. The inner struct is updated using a mutable copy of point
for (index, group) in dataStruct.group.enumerated() {
if group.point.contains(where: { $0.address.index == pointNo }) {
var copy = group
copy.point = group.point.reduce(into: []) {
if $1.address.index == pointNo {
var pointCopy = $1
pointCopy.presentValue = "new value"
$0.append(pointCopy)
} else {
$0.append($1)
}
}
dataStruct.group[index] = copy
}
}