Итак, я должен был отфильтровать трехмерный массив объектов на основе имени объекта, содержащего текст, введенный пользователем. Выход должен быть плоским массивом 1, и родительский массив также должен быть включен. Соответствующий объект должен быть на любом уровне глубины.
вот модель данных:
let data = [
Category(
id: "1",
name: "Stationary",
iconImageUrl: nil,
parent: nil,
tree: 1,
rootId: 1,
child: [
Category(
id: "2",
name: "Office Stationary",
iconImageUrl: nil,
parent: 1,
tree: 2,
rootId: 1,
child: [
Category(id: "3", name: "Pen", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "4", name: "Pencil", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "5", name: "Ruler", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "6", name: "Paper", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil)
],
rgbColor: nil
),
Category(
id: "7",
name: "Home Stationary",
iconImageUrl: nil,
parent: 1,
tree: 2,
rootId: 1,
child: [
Category(id: "8", name: "Telephone", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "9", name: "Fax", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "10", name: "Komputer", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "11", name: "Laptop", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil)
],
rgbColor: nil
)
],
rgbColor: nil
)
]
на данный момент я придумал нечто подобное, но это снижает производительность моего приложения. потому что он использует цикл for, я думаю
var searchText = "pen"
var filteredCategories: [Category] = []
// Loop 1
for parent in data.value {
if let child = parent.child {
// Loop 2
for firstChild in child {
if let child = firstChild.child {
// Loop 3
for secondChild in child {
// Check if the last array contains search text
if secondChild.name!.range(of: searchText, options: .caseInsensitive) != nil {
// Check if the result has already 1st array so it wont duplicates
if !filteredCategories.contains(where: { $0.name == parent.name }) {
filteredCategories.append(parent)
}
// Check if the result has already contain 2nd array so it wont duplicates
if !filteredCategories.contains(where: { $0.name == firstChild.name }) {
filteredCategories.append(firstChild)
}
filteredCategories.append(secondChild)
}
}
}
if firstChild.name!.range(of: searchText, options: .caseInsensitive) != nil {
if !filteredCategories.contains(where: { $0.name == parent.name }) {
filteredCategories.append(parent)
}
if !filteredCategories.contains(where: { $0.name == firstChild.name }) {
filteredCategories.append(firstChild)
}
}
}
}
if parent.name!.range(of: searchText, options: .caseInsensitive) != nil {
if !filteredCategories.contains(where: { $0.name == parent.name }) {
filteredCategories.append(parent)
}
}
}
Результат должен быть таким:
let result = [
Category(
id: "1",
name: "Stationary",
iconImageUrl: nil,
parent: nil,
tree: 1,
rootId: 1,
child: [
Category(
id: "2",
name: "Office Stationary",
iconImageUrl: nil,
parent: 1,
tree: 2,
rootId: 1,
child: [
Category(id: "3", name: "Pen", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "4", name: "Pencil", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "5", name: "Ruler", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "6", name: "Paper", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil)
],
rgbColor: nil
),
],
rgbColor: nil),
Category(
id: "2",
name: "Office Stationary",
iconImageUrl: nil,
parent: 1,
tree: 2,
rootId: 1,
child: [
Category(id: "3", name: "Pen", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "4", name: "Pencil", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "5", name: "Ruler", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
Category(id: "6", name: "Paper", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil)
],
rgbColor: nil
),
Category(id: "3", name: "Pen", iconImageUrl: nil, parent: 2, tree: 3, rootId: 1, child: nil, rgbColor: nil),
]
Не показывать и не ссылаться на изображения кода. Это текст. Скопируйте и вставьте модель данных в вопрос.
Также, пожалуйста, попробуйте уточнить, в чем вопрос. Приведите пример ввода, желаемого результата и того, что идет не так. Спасибо!
привет, Мэтт, спасибо за вклад, извините за ошибку, я уже обновил свой вопрос, надеюсь, он был достаточно ясен
Хорошо, спасибо. Но я не понимаю логики, по которой ввод должен генерировать вывод. Можете ли вы объяснить словами, в чем заключается цель?
Итак, мне дали текст для поиска, и я должен был отфильтровать 3D-массив по их имени на основе этого текста. Выход должен быть 1 плоским массивом, и родительский массив также должен быть включен
Итак, в примере первым шагом будет поиск «ручки» в качестве имени (или в названии) категории на любой глубине? Или заранее известно, что нам нужно смотреть только на глубину 3?
да, это будет поиск имени объекта, содержащего «перо» на любой глубине, но этот родительский объект также должен быть включен
Известно ли, что существует только одна такая категория? То есть, когда я найду категорию "ручка", я могу остановиться?
нет, это может быть много категорий, а также если имя объекта содержит «ручка», но не должно быть повторяющихся категорий.
К сожалению, мы не смогли переопределить категорию, поскольку модель категории получена из API JSON OBJECT.
Не по теме, но зачем позволять внешнему API решать, как вы проектируете свои объекты модели? Почему бы не создать дизайн, который подходит вам лучше всего, и написать код преобразования, чтобы сопоставить дизайн API и ваш дизайн? (Отвечать не обязательно, это скорее риторический вопрос)
Этот код можно исправить с помощью функций более высокого порядка, но в будущем, если вы столкнетесь со случаями, когда необходимы такие большие циклы, ваш код получит большую пользу от
guard
и раннего возврата вместо глубоко вложенных операторовif
, таких как это