По своей сути это проблема структуры данных. Вы выполняете линейный поиск по всем своим данным, чтобы найти что-то с указанием c headerName
, tabId
, rowId
. Это сложно, грязно и медленно (O(headerCount * tabCount * rowCount)
!)
Если бы использовались словари, это могло бы быть просто:
self.model.data[0].data[0]
.filters[headerName]
.data[tabId]
.data[rowId]
.isSelected
.toggle()
Если массивы должны остаться, вы можете очистить это много путем извлечения общих частей для именованных локальных переменных. Инверсия операторов if
(в данном случае, в операторы guard
) также экономит тонну вложенности:
func selectedStateUpdated(headerName: String, tabId: String, rowId: String){
let data = self.model.data[0].data[0] // TODO: name me better
for currIndex in 0..<data.filters.count {
let filter = data.filters[currIndex]
guard filter.headerName == headerName else { return }
for tabIdx in 0..<filter.data.count {
let tab = filter.data[tabIdx]
guard tab.id == tabId else { continue }
for rowItemIdx in 0..< tab.data.count {
let rowItem = tab.data[rowItemIdx]
guard rowItem.id == rowId else { continue }
self.model.data[0].data[0]
.filters[currIndex]
.data[tabIdx]
.data[rowItemIdx]
.isSelected
.toggle()
}
}
}
}
Это можно еще улучшить, используя zip
для получения индексов и элементов в один выстрел:
func selectedStateUpdated(headerName: String, tabId: String, rowId: String){
let data = self.model.data[0].data[0] // TODO: name me better
for (currIndex, filter) in zip(data.filters.indices, data.filters) {
guard filter.headerName == headerName else { return }
for (tabIdx, tab) in zip(filter.data.indices, filter.data) {
guard tab.id == tabId else { continue }
for (rowItemIdx, rowItem) in zip(tab.data.indices, tab.data) {
guard rowItem.id == rowId else { continue }
self.model.data[0].data[0]
.filters[currIndex]
.data[tabIdx]
.data[rowItemIdx]
.isSelected
.toggle()
}
}
}
}