Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering Array and displaying in Table View?

I want to search an dictionary of exercises for the name key and then show the filtered result in the table view. I am using this function

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    let filtered = exercises.filter { $0["name"] == searchText }
    print(filtered)

    if(filtered.count == 0){
        searchActive = false;
    } else {
        searchActive = true;
    }
    self.exercisesTableView.reloadData()
}

Variables:

var exercises = [Exercise]()
var filtered: [NSMutableArray] = []
var searchActive: Bool = false

In the search function I get the error

Type'Exercise' has no subscript members

and then i have the issue that the result is an NSMutableArray and so I cant set the result names as cell text to display

Cannot convert value of type 'NSMutableArray' to type 'String' in coercion

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    if (searchActive){
        cell.textLabel?.text = filtered[indexPath.row] as String
    } else {
        let exercise = exercises[indexPath.row]

        cell.textLabel!.text = exercise.name
    }
    return cell
}

Here is my Exercise dictionary for reference:

final public class Exercise {
    var id: Int
    var descrip: String
    var name: String
    var muscles: [Int]
    var equipment: [Int]

    public init?(dictionary: [String: Any]) {

        guard
            let id = dictionary["id"] as? Int,
            let descrip = dictionary["description"] as? String,
            let name = dictionary["name"] as? String,
            let muscles = dictionary["muscles"] as? [Int],
            let equipment = dictionary["equipment"] as? [Int]

            else { return nil }

        self.id = id
        self.descrip = descrip
        self.name = name
        self.muscles = muscles
        self.equipment = equipment

    }

I can fix the second error by making var filtered: [String] = [] so it can be used as a cell title, but that doesnt resolve the first error and im not sure is the right way to go about it?

like image 236
infernouk Avatar asked Dec 14 '22 02:12

infernouk


1 Answers

Your filtered also type of [Exercise] and you need to filter it like.

var filtered = [Exercise]() 

self.filtered = exercises.filter { $0.name == searchText }

Here $0 is type of Exercise object, so you need to access its property name using $0.name.

Edit: If you want filtered as type of [String] with only name then you can need to use both map and filter like this.

self.filtered = exercises.filter { $0.name == searchText }.map { $0.name }

OR

self.filtered = exercises.map { $0.name }.filter { $0 == searchText }

OR directly using filterMap as @dfri suggested.

self.filtered = exercises.flatMap{ $0.name == searchText ? $0.name : nil }
like image 136
Nirav D Avatar answered Mar 29 '23 05:03

Nirav D