6

I have a struct, which is my data model:

import Foundation

struct Item : Codable {

var cat:String
var name:String
var createdAt:Date
// more 
var itemIdentifier:UUID
var completed:Bool

func saveItem() {
    DataManager.save(self, with: itemIdentifier.uuidString)
}

func deleteItem() { DataManager.delete(itemIdentifier.uuidString)
}

mutating func markAsCompleted() {
    self.completed = true
    DataManager.save(self, with: itemIdentifier.uuidString)
}

}

Then in my ViewController I have the following code to load the data, which goes into a TableView (sorted by the creation date).

func loadData() {
    items = [Item]()
    items = DataManager.loadAll(Item.self).sorted(by: {
        $0.createdAt < $1.createdAt })
    tableView.reloadData()
}

Now I would like to add a filter, so that only category goes into the TableView. For instance, only where cat equals "garden".

How can I add that?

2 Answers 2

19

Use filtered.

Here is an example of your unfiltered array:

var unfilteredItems = ...

Here is a filtering code:

var filteredItems = unfilteredItems.filter { $0.cat == "garden" }

Here is the code:

func loadData() {
    items = [Item]()
    items = DataManager.loadAll(Item.self).sorted(by: {
        $0.createdAt < $1.createdAt }).filter { $0.cat == "garden"}

    tableView.reloadData()
}
Sign up to request clarification or add additional context in comments.

5 Comments

I added the line after my "items = DataManager" code. Is the array then still sorted? (so filtered and sorted).
Last time I remember functional programming, I think so because filtering keeps the elements in place. Let me now if it doesn't.
Pretty sure @HuyVo is correct on this. Your sort should stay in place. If it doesn't just put the sorted call after the filter.
@arakweker filter will not affect the order of the remaining elements, but if you plan on applying the filter directly, you should still filter prior to sorting. With the solution above you will sort the full item list (sorting: "expensive"), and thereafter filter away possibly large part of it. If you conversily perform the cheaper filter first, the sorting can be performed on a smaller list of items.
@dfri... seems a good advice. But first sorting and then filtering gives the right result. The other way around (first filtering and then sorting) doesn't.
0
    let arrTmp = arr.filter({$0.name.localizedCaseInsensitiveContains("Hi")})
        arrLocations = arrTmp

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.