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

发布于 2025-01-24 17:43:09 字数 1174 浏览 2 评论 0原文

我有多层结构,将复杂的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中的组是“让”恒定的。 基本上,该函数应该比较结构中的 address.index 字段与传递的 pointno 变量,并且一旦找到(唯一),point.prosent.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 }
            }
        }
    }

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最冷一天 2025-01-31 17:43:09

基本上有两种方法。

  • 通过将它们分配给变量,修改它们并将它们重新分配到其位置dataCoStruct

    来提取对象。

  • 枚举数组并修改对象。

这是第二种方式的一个例子

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

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"
            }
        }
    }
 }
嗼ふ静 2025-01-31 17:43:09

处理多级结构时,它变得更加复杂,但是这是我们首先通过group枚举的一种方法,因此我们同时获得了每个迭代的对象和对象的索引更新group数组时索引。内部结构使用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
    }
}

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
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文