You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift嵌套数组中根据ID更新指定层级的Item?

如何在嵌套的Item数组中通过ID更新任意层级的元素

我需要实现通过ID找到嵌套数组中任意层级的ItemType元素,并更新其name属性。当前的updateName方法只能处理第一层数组的元素,无法处理层级不确定的深层嵌套元素(比如示例中的item1、item2、item4),请问该如何实现?

解决方案

由于ItemType是值类型(struct),修改深层元素时需要通过递归遍历并生成新实例来替换原有元素,这样才能触发@Published的更新通知,让SwiftUI视图同步刷新。以下是修改后的完整代码:

import SwiftUI

@main
struct findItem_testApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(ItemModel.shared)
        }
    }
}

struct ContentView: View {
    @EnvironmentObject var itemModel: ItemModel
    
    var body: some View {
        VStack {
            MyView(item: itemModel.items[0])
            MyView(item: itemModel.items[1].nestedItems[0].nestedItems[0])
            MyView(item: itemModel.items[1].nestedItems[0])
            MyView(item: itemModel.items[1])
            MyView(item: itemModel.items[2].nestedItems[0])
            MyView(item: itemModel.items[2])
        }
    }
}

struct MyView: View {
    let item: ItemType
    
    var body: some View {
        Text(item.name)
            .bold()
            .padding()
            .onTapGesture {
                print(item.name, item.id)
                ItemModel.shared.updateName(id: item.id, value: item.name + " updated!")
            }
    }
}

struct ItemType: Identifiable {
    let id: UUID
    var name: String
    var nestedItems: [ItemType]
    
    init(name: String, nestedItems: [ItemType]) {
        self.id = UUID()
        self.name = name
        self.nestedItems = nestedItems
    }
}

let item0: ItemType = ItemType(name: "item0", nestedItems: [])

let item1: ItemType = ItemType(name: "item1", nestedItems: [])
let item2: ItemType = ItemType(name: "item2", nestedItems: [item1])
let item3: ItemType = ItemType(name: "item3", nestedItems: [item2])

let item4: ItemType = ItemType(name: "item4", nestedItems: [])
let item5: ItemType = ItemType(name: "item5", nestedItems: [item4])

class ItemModel: ObservableObject {
    static let shared: ItemModel = ItemModel()
    
    @Published var items: [ItemType] = []
    
    init() {
        self.items = [item0, item3, item5]
    }
    
    func updateName(id: UUID, value: String) {
        // 递归遍历并更新目标元素
        func updateRecursive(_ currentItem: ItemType) -> ItemType {
            if currentItem.id == id {
                return ItemType(name: value, nestedItems: currentItem.nestedItems)
            }
            let updatedNestedItems = currentItem.nestedItems.map(updateRecursive)
            return ItemType(name: currentItem.name, nestedItems: updatedNestedItems)
        }
        
        // 替换顶层数组触发更新
        items = items.map(updateRecursive)
    }
}

关键逻辑说明

  1. 递归遍历更新:在updateName内部定义了updateRecursive递归函数,会逐层检查元素ID:
    • 如果当前元素ID匹配目标ID,返回替换了name的新实例
    • 如果不匹配,递归处理当前元素的nestedItems数组,生成更新后的子元素集合,再返回当前元素的新实例
  2. 触发视图刷新:通过map生成全新的顶层items数组并赋值,@Published会监听数组的替换操作,自动通知SwiftUI视图刷新显示最新内容。

内容的提问来源于stack exchange,提问作者swiftPunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:44:52