Как найти нужный элемент внутри вложенного элемента массива?

У меня есть такая структура в коде, которая является идентифицируемой и имеет вложенные элементы:

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]()

Моя проблема заключается в том, что после создания массива, если мне нужно обновить элемент, я знаю идентификатор этого элемента, но не знаю, как найти этот идентификатор и найти его правильно. посмотрите на эту фотографию, я могу просмотреть каждый элемент myArray, чтобы найти элемент, соответствующий моему идентификатору поиска, и если в элементах myArray нет элемента, который я ищу, мне придется начать искать внутри вложенных элементов каждого элемента массива, что заняло бы массу времени. Хотите узнать, есть ли более быстрый способ найти нужный предмет.

Насколько велик ваш массив и подмассивы? Если элементов не так много, простой алгоритм поиска в глубину может подойти для ваших нужд. Если у вас достаточно памяти, но вам нужна более высокая скорость поиска, вы можете попробовать использовать словарь. Ключом будет идентификатор, а значением — объект Item.

AlexanderJCS 02.09.2024 05:46

Он большой, например, 50000 или 100000 элементов, я могу изменить массив на словарь, например var myDic: [string : Item] = [string : Item]() какая строка будет UUID.string также в элементе, но в конце мне придется зацикливать или фильтровать каждый слой за слоем, что будет та же проблема снова.

swiftPunk 02.09.2024 05:53

Но поиск ключей каждого словаря будет быстрым.

Joakim Danielson 02.09.2024 09:20

При наличии от 50 до 100 тысяч объектов, возможно, вам лучше сохранить их в базе данных и позволить механизму базы данных выполнять поиск.

Joakim Danielson 02.09.2024 09:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для ... 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 используйте рекурсию, например:

 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
 }

 

РЕДАКТИРОВАТЬ-1:

Вы можете использовать тот же подход (рекурсию) для создания словаря [UUID: Item] один раз. После этого вы можете напрямую получить доступ/обновить желаемый идентификатор элемента, без каких-либо дополнительных затрат на доступ.

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
 }
 
 

Большое спасибо. Точно так же, как я уже упоминал в своем вопросе, вы также просматриваете каждый элемент один за другим.

swiftPunk 02.09.2024 08:39

Вы можете использовать тот же подход (рекурсию) для создания словаря [UUID: Item] один раз. После этого вы сможете напрямую получить доступ к нужному идентификатору элемента без каких-либо накладных расходов. Обновил мой ответ, чтобы использовать словарь.

workingdog support Ukraine 02.09.2024 09:17

Другие вопросы по теме