Фильтрация массива для заполнения списка

#swift #macos #swiftui #macos-big-sur

Вопрос:

ObservableObject У меня есть модель данных, состоящая из следующей структуры:

 struct Task: Codable, Hashable, Identifiable {
    var id = UUID()
    var title: String
    var completed = false
    var priority = 2
}
 

Простая структура для списка задач в моем приложении.

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

Я все еще новичок в swift, но после некоторого поиска в Интернете (и попытки сделать это специально) я попытался:

 struct TasksView: View {
    
    @EnvironmentObject private var taskdata: DataModel
    @State var byPriotity: Int
        
    // this of course fails. 
    let filtered = taskdata.tasks.filter { priority in
        return taskdata.$tasks.priority = byPriotity        
    }
    
    var body: some View {
      //...
    }
}
 

Идея состоит в том, чтобы перейти filtered к списку и отобразить его в представлении. Если пользователь выбирает другую кнопку, затем повторите, отфильтруйте для нового приоритета и отобразите.

Как отфильтровать @EnvironmentObject private var taskdata: DataModel по приоритету?

Спасибо.

Ответ №1:

Я бы, вероятно, сделал это функцией DataModel , а не пытался сделать это на View :

 class DataModel : ObservableObject {
    @Published var tasks : [Task] = []
    
    func filteredTasks(byPriority priority: Int) -> [Task] {
        tasks.filter { $0.priority == priority }
    }
}
 

А затем в View , он будет использоваться как:

 var body : some View {
  ForEach(taskdata.filteredTasks(byPriority: byPriority)) { task in 
    //...
  }
}
 

Если бы вы действительно хотели сохранить его View , вы могли бы сделать это:

 var filteredTasks: [Task] {
    taskdata.tasks.filter { $0.priority == byPriotity }
}
 

Комментарии:

1. Это вроде как работает. Я думаю, что делать это на уровне модели данных хорошо, у меня там уже есть функция «сортировки». Однако, если я хочу отобразить ВСЕ задачи независимо от приоритета, это вызывает у меня проблемы…. Как вы вернете все tasks , если, скажем, я пройду priority = 3 , чтобы показать все?

2. Что вы хотите показать в этом случае? Все они или те, у кого приоритет 3? Или вы хотите, чтобы они были отсортированы по приоритету?

3. Все они. Прямо сейчас у меня есть 0, 1 и 2. Я действительно, если я пройду 3, все они будут показаны. Я пытался добавить if priority == 3 return the full array else .. your code , но получал всевозможные ошибки

4. Ты мог бы сделать это: tasks.filter { priority == 3 || $0.priority == priority }