代码之家  ›  专栏  ›  技术社区  ›  swiftPunk

如何更新数组中嵌套项内的所需项?

  •  1
  • swiftPunk  · 技术社区  · 1 年前

    我想更新嵌套项目数组中的一个项目,以显示我在下面的示例代码中提出的问题,这个问题的重点是更新嵌套项目,而不是SwiftUI技巧。我想找到一个知道其id并在找到后尝试更新的项目。在下面的代码中,我向您展示了更新第一层项目的示例,但只要层更深,我们就无法猜测它可能是2层还是10层,我们不知道。 我怎样才能更新 项目1 , 项目2 项目4 ?

    enter image description here

        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)
                        // need to update item.name from model
                        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] = [ItemType]()
            
            init() {
                self.items = [item0, item3, item5]
            }
        
            func updateName(id: UUID, value: String) {
        
                for i in (0 ..< self.items.count) {
        
                    if (self.items[i].id == id) {
                        self.items[i].name = value
                        break
                    }
        
                }
         
            }
        
        }
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   Sash Sinha    1 年前

    a怎么样 recursive 方法:

    import Foundation
    
    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
        }
    }
    
    class ItemModel {
        var items: [ItemType]
    
        init(items: [ItemType]) {
            self.items = items
        }
    
        func updateName(id: UUID, newName: String) {
            updateNameRecursively(id: id, newName: newName, items: &self.items)
        }
    
        private func updateNameRecursively(id: UUID, newName: String, items: inout [ItemType]) {
            for i in 0..<items.count {
                if items[i].id == id {
                    items[i].name = newName
                    return 
                } else {
                    updateNameRecursively(id: id, newName: newName, items: &items[i].nestedItems)
                }
            }
        }
    }
    
    extension ItemModel {
        func prettyPrintItems(items: [ItemType], indentLevel: Int = 0) {
            let indent = String(repeating: "  ", count: indentLevel)
            for item in items {
                print("\(indent)- \(item.name) (id: \(item.id))")
                prettyPrintItems(items: item.nestedItems, indentLevel: indentLevel + 1)
            }
        }
    }
    
    let item0 = ItemType(name: "item0")
    let item1 = ItemType(name: "item1")
    let item2 = ItemType(name: "item2", nestedItems: [item1])
    let item3 = ItemType(name: "item3", nestedItems: [item2])
    let item4 = ItemType(name: "item4")
    let item5 = ItemType(name: "item5", nestedItems: [item4])
    let model = ItemModel(items: [item0, item3, item5])
    print("Before:")
    model.prettyPrintItems(items: model.items)
    model.updateName(id: item1.id, newName: "item1 updated!")
    model.updateName(id: item2.id, newName: "item2 updated!")
    model.updateName(id: item4.id, newName: "item4 updated!")
    print("After:")
    model.prettyPrintItems(items: model.items)
    

    输出:

    Before:
    - item0 (id: CE42EA37-3841-4D4C-931D-0611FC80E1F0)
    - item3 (id: 0EADCD5E-C24B-495A-9581-97DEC427B859)
      - item2 (id: 44103D4A-0871-4235-B895-4AD16C3AABB0)
        - item1 (id: 0412FC6B-B5A4-4AFB-8BF4-C4569EBA16E7)
    - item5 (id: 4C396B6A-1FA7-4E7B-AE6C-EE4B10395AB6)
      - item4 (id: 5CA53EA0-D229-429C-812E-A364EE725B89)
    After:
    - item0 (id: CE42EA37-3841-4D4C-931D-0611FC80E1F0)
    - item3 (id: 0EADCD5E-C24B-495A-9581-97DEC427B859)
      - item2 updated! (id: 44103D4A-0871-4235-B895-4AD16C3AABB0)
        - item1 updated! (id: 0412FC6B-B5A4-4AFB-8BF4-C4569EBA16E7)
    - item5 (id: 4C396B6A-1FA7-4E7B-AE6C-EE4B10395AB6)
      - item4 updated! (id: 5CA53EA0-D229-429C-812E-A364EE725B89)