Как отредактировать запись после поиска и фильтрации?

searchbar
tableview

#1

Привет всем!

Подскажите, пожалуйста, такой вопрос. Есть таблица со списком элементов. По нажатию строки можно перейти на Detail и посмотреть или отредактировать выбранную запись. Затем на экране со списком элементов добавлена функциональность поиска и фильтрации. Все стандартно, все работает нормально, элементы находятся, список фильтруется в отдельный массив и из фильтрованного списка можно также перейти на страницу с деталями о выбранной записи.

Но каким образом после этого вернуть на основной экран отредактированное значение записи? Ведь получается, что передается запись из второго, отфильтрованного массива. И возврат тоже осуществляется на отфильтрованный список. И если значение было изменено, то оно меняется в этом отфильтрованном списке, со своим индексом, но не в основном, где у этой записи другой индекс. Как изменить значение в основном списке?


#2

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


#3

Спасибо за ответ. А подскажите, пождалуйста, более подробно. Ведь при поиске практически везде показывают создание второго, отфильтрованного массива.

Как же тогда сделать с одним массивом? Может есть какой-то пример кода?


#4

Без фильтра заполняете массив всеми записями.
После филтра заполняете этот же массив отфильтрованными записями.
Все просто.
Только редактирование записи сохраняете там, где хранятся все записи.


#5

вы имеете в виду такой код?

var cast = ["Vivien", "Marlon", "Kim", "Karl"]
cast = cast.filter { $0.count < 5 }
print(cast)

//Prints “[“Kim”, “Karl”]”

Но ведь в этом случае затирается предыдущий массив, который полный.


#6

Видимо я не до конца понял вашу логику. Первый массив у вас скорее всего выступает в качестве хранилища всех записей.
В таком случае используйте второй массив для вывода всех записей и отфильтрованных.

let storage = [...]
var itemsArray: [String] = []

// поиска нету
itemsArray = storage
tableView.reloadData()

// поиск включен
itemsArray = storage.filter { ... }
tableView.reloadData()

редактирование будет происходить в массиве storage, не по индексу, а по ключу (ID к примеру)


#7

Спасибо, что помогаете! Примерно так и сделал, не спасло ))

Вот сейчас добрался до следующего: если модель объекта задать классом, то изменение значения экземпляра в отфильтрованном списке меняет и значение в общем списке. Т.е., в этом случае выручает ссылочный тип.

class Season {
    var name: String
    var number: Int
    
init(name: String, number: Int) {
    self.name = name
    self.number = number
}
}
var spring = Season(name: "Spring", number: 92)
var summer = Season(name: "Summer", number: 92)
var fall = Season(name: "Autumn", number: 91)
var winter = Season(name: "Winter", number: 90)

var seasons = [spring, summer, fall, winter]

var seasonsFiltered = seasons.filter { $0.name.contains("m") }

seasonsFiltered // [{name "Summer", number 92}, {name "Autumn", number 91}]

seasonsFiltered[1].name = "Fall"

print(seasonsFiltered[1].name) // Prints - Fall
print(seasons[2].name) // Prints - Fall

Но это работает только если изменяется значение. Если же значение удаляется, или добавляется, то это не срабатывает. Т.е., в общем, не отфильтрованном массиве, остается значение, удаленное в отфильтрованном массиве, и не появляется значение, добавленное в отфильтрованном массиве.


#9

Вам нужно все изменения делать в исходном массиве. После чего пересобирать второй массив, в зависимости от того был ли у вас поиск или нет.


#10

Там немного сложнее из-за разных индексов.

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


#11

Эта задача почти в каждом проекте есть.
Индексы тут совсем не причем. Поиск нужно делать по ID.


#12

о каком ID вы говорите? Ведь здесь используется массив.


#13

Это в упращенном виде у вас. В реальности будет массив объектов.
Но у и вас не сложно делать поиск по значению.
Либо расширьте свой массив, добавив каждой записи ID.


#14

Спасибо за подсказку!
Да, поиск по значению возможен, единственное, что есть вероятность дублей. ID в этом случае лучше.
А как сделать автоматическую нумерацию для свойства ID в массиве объектов?


#15

Уникальные ID - UUID().string вроде так


#16

Спасибо за помощь! Я правда реализовал немного иначе. Добавил в модель данных логическое свойство и по нему отлавливал значение в неотфильтрованном массиве. И здесь конечно нужно, чтобы модель данных была классом, т.е. ссылочным типом. Только тогда возможно отловить обратную связь между значением из отфильтрованного массива с тем же значением в полном, неотфильтрованном массиве.