Search code examples
swift

How to find the needed item inside a nested item in an array?


I have a struct like this in code, which is Identifiable and has nested items as well:

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

}

var myArray: [Item] = [Item]()

My issue is after building my array, if I need to update an item I know the id of that Item but I do not know how to look for that id and find it in correct way. look this photo, I can look each item of myArray to find the item that match to my looking id, and if myArray items dose not have the item I am looking for, I have to start looking inside of nested items of each array item, which would take tons of time. Looking to find out if there is a faster way to find the needed item. enter image description here


Solution

  • To ... update an item I know the id of that Item but I do not know how to look for that id and find it in correct way, use recursion, such as:

     func findItem(withID id: UUID, in items: [Item]) -> Item? {
         for item in items {
             if item.id == id {
                 return item
             }
             if let foundItem = findItem(withID: id, in: item.nestedItems) {
                 return foundItem
             }
         }
         return nil
     }
    
     
    

    EDIT-1:

    You can use the same approach (recursion) to construct a Dictionary [UUID: Item] once. Then after that, you can directly access/update the desired item id, no overhead to access.

    var itemDictionary = createItemDictionary(items: myArray)
     
     itemDictionary[item2.id]?.nameOfItem = "Mickey Mouse"  // <--- here
     
     func createItemDictionary(items: [Item]) -> [UUID: Item] {
         var itemDictionary: [UUID: Item] = [:]
         for item in items {
             itemDictionary[item.id] = item
             itemDictionary.merge(createItemDictionary(items: item.nestedItems)) { (_, new) in new }
         }
         return itemDictionary
     }