Search code examples
swiftmacosswiftuimacos-big-sur

Filtering an array to populate a list


I have a ObservableObject with my data model, composed of the following struct:

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

A simple struct for a todo list within my app.

In the view in charge of building the list of tasks to display by priority, I would like to filter this data model by each element's priority, and display it on the list.

I'm still new to swift, but after some googling (and trying this specifically), I have tried:

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 {
      //...
    }
}

The idea is to pass filtered to the list and have that be displayed on the view. If the user selects a different button, then repeat, filter for the new priority and display.

How do I filter @EnvironmentObject private var taskdata: DataModel per `priority?

Thank you.


Solution

  • I'd probably make this a function on the DataModel rather than trying to do it on the View:

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

    And then in the View, it'd be used like:

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

    If you really wanted to keep it on the View, you could do this:

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