У меня есть такая структура в коде, которая является идентифицируемой и имеет вложенные элементы:
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 нет элемента, который я ищу, мне придется начать искать внутри вложенных элементов каждого элемента массива, что заняло бы массу времени. Хотите узнать, есть ли более быстрый способ найти нужный предмет.
Он большой, например, 50000 или 100000 элементов, я могу изменить массив на словарь, например var myDic: [string : Item] = [string : Item]()
какая строка будет UUID.string также в элементе, но в конце мне придется зацикливать или фильтровать каждый слой за слоем, что будет та же проблема снова.
Но поиск ключей каждого словаря будет быстрым.
При наличии от 50 до 100 тысяч объектов, возможно, вам лучше сохранить их в базе данных и позволить механизму базы данных выполнять поиск.
Для ... 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
}
Большое спасибо. Точно так же, как я уже упоминал в своем вопросе, вы также просматриваете каждый элемент один за другим.
Вы можете использовать тот же подход (рекурсию) для создания словаря [UUID: Item]
один раз. После этого вы сможете напрямую получить доступ к нужному идентификатору элемента без каких-либо накладных расходов. Обновил мой ответ, чтобы использовать словарь.
Насколько велик ваш массив и подмассивы? Если элементов не так много, простой алгоритм поиска в глубину может подойти для ваших нужд. Если у вас достаточно памяти, но вам нужна более высокая скорость поиска, вы можете попробовать использовать словарь. Ключом будет идентификатор, а значением — объект
Item
.