Flo
Flo

Reputation: 449

How to display the count of a filtered array of objects

I have an array of objects which represent few Sections. Each Section contains a number of items. I managed to filter all sections to display the wanted items in my UITableView but I can't manage to get the right count of items from my sections. Every time after I filter the array I get the original count of items. My console is saying: Number of items in each section: [9, 6] but in reality in my UITableView are only [6, 5]. How can I reflect the right amount of items to use my array forward ? Here is my code:



// MARK : MODEL
class ChecklistItemSection{

    var name: String // name of the section
    var checklistItems: [ChecklistItem] // all items from Checklist

    init(named: String, checklistItems: [ChecklistItem]) {

        self.name = named
        self.checklistItems = checklistItems
    }

    class func checklistItemSections() -> [ChecklistItemSection] {

        var allSections = [vehicleCheck(), viewingScreen(), batteryUnitAndFridge()]

        for (index, section) in allSections.enumerated() {
            if(section.checklistItems.count < 1) {
                allSections.remove(at: index)
            }
        }
        return allSections
    }

    // Private methods
    private class func vehicleCheck() -> ChecklistItemSection {

        var checklistItems = [ChecklistItem]()

        checklistItems.append(ChecklistItem(templateID: 109, lineID: 3, poolID: 10, descript: "Tyres - Wear/Damage/Bulges/Cuts/Flat tyres", showVehicle: false, showTrailer: true, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 4, poolID: 22, descript: "Vehicle and trailer coupling: undamaged and safety locking device working", showVehicle: true, showTrailer: false, highlight: true, pg9: true, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 7, poolID: 20, descript: "Exhaust - Condition/Emission (Excess smoke)", showVehicle: true, showTrailer: false, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 3, poolID: 10, descript: "Tyres - Wear/Damage/Bulges/Cuts/Flat tyres", showVehicle: true, showTrailer: false, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 4, poolID: 22, descript: "Vehicle and trailer coupling: undamaged and safety locking device working", showVehicle: true, showTrailer: true, highlight: true, pg9: true, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 7, poolID: 20, descript: "Exhaust - Condition/Emission (Excess smoke)", showVehicle: false, showTrailer: true, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 3, poolID: 10, descript: "Tyres - Wear/Damage/Bulges/Cuts/Flat tyres", showVehicle: false, showTrailer: true, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 4, poolID: 22, descript: "Vehicle and trailer coupling: undamaged and safety locking device working", showVehicle: true, showTrailer: true, highlight: true, pg9: true, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 109, lineID: 7, poolID: 20, descript: "Exhaust - Condition/Emission (Excess smoke)", showVehicle: false, showTrailer: true, highlight: false, pg9: false, imagesPath: [])!)

        return ChecklistItemSection(named: "Section 1", checklistItems: checklistItems)
    }

    private class func viewingScreen() -> ChecklistItemSection {

        var checklistItems = [ChecklistItem]()

        checklistItems.append(ChecklistItem(templateID: 38, lineID: 28, poolID: 16, descript: "Windscreen Wipers & Washers are they effective?", showVehicle: true, showTrailer: false, highlight: false, pg9: false, imagesPath: [])!)

        checklistItems.append(ChecklistItem(templateID: 38, lineID: 28, poolID: 16, descript: "Water Level - In cab indicator", showVehicle: true, showTrailer: false, highlight: false, pg9: false, imagesPath: [])!)

        return ChecklistItemSection(named: "Section 2", checklistItems: checklistItems)
    }

    private class func batteryUnitAndFridge() -> ChecklistItemSection {

        var checklistItems = [ChecklistItem]()

        checklistItems.append(ChecklistItem(templateID: 38, lineID: 31, poolID: 38, descript: "Battery is held securely in place by the correct means (not cables)", showVehicle: true, showTrailer: true, highlight: false, pg9: true, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 38, lineID: 32, poolID: 39, descript: "Battery cables and pins secure", showVehicle: true, showTrailer: true, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 38, lineID: 33, poolID: 40, descript: "Battery is not leaking", showVehicle: true, showTrailer: true, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 38, lineID: 34, poolID: 38, descript: "Battery is held securely in place by the correct means (not cables)", showVehicle: true, showTrailer: true, highlight: false, pg9: true, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 38, lineID: 35, poolID: 39, descript: "Battery cables and pins secure", showVehicle: false, showTrailer: true, highlight: false, pg9: false, imagesPath: [])!)
        checklistItems.append(ChecklistItem(templateID: 38, lineID: 35, poolID: 39, descript: "Battery is not leaking", showVehicle: true, showTrailer: false, highlight: false, pg9: false, imagesPath: [])!)

        return ChecklistItemSection(named: "Section 3", checklistItems: checklistItems)
    }
}

class ChecklistItem {

    var showVehicle: Bool
    var showTrailer: Bool
}

// MARK: VC

class ChecklistVC: UIViewController {

    lazy var checklistItem: [ChecklistItemSection] = { return ChecklistItemSection.checklistItemSections() }()

    override func viewDidLoad() {
        super.viewDidLoad()

        filterQuestions()
    }

    func filterQuestions() {

        // Show only the questions available for Trailer
        if vehicleRegistrationNumber.isBlank {

            checklistItem.forEach {
                $0.checklistItems.forEach {
                    if $0.showVehicle {
                        $0.showVehicle = false
                    }
                }
            }

            checklistItem = checklistItem.filter { $0.checklistItems.filter { $0.showTrailer && !$0.showVehicle }.count != 0 }.filter {$0.checklistItems.count > 0}
        }

        print("Number of items in each section: \(checklistItem.map {$0.checklistItems.count})") // I get [9, 6] every time. But it should display [6, 5] reflecting the items after filtering.
    }
}

Thanks for reading this !

Upvotes: 0

Views: 71

Answers (1)

Sweeper
Sweeper

Reputation: 271645

As you know, filter doesn't actually remove the items. It just returns a new array with some items removed. So when you are doing a nested filter like this:

checklistItem.filter { $0.checklistItems.filter { ... }.count != 0 }

It will return checklistItem but with some elements removed, and you assign this result to checklistItem, hence changing it. But note that the inner arrays of checklistItem (i.e. checkListItems) are not changed!

The inner filter only returns a new array (, and doesn't actually modify the array itself) as well.

I suggest you to forEach thing in checklistItem, removeAll that satisfy the criteria, then remove all of the checklistItems that are empty by using another removeAll:

checklistItem.forEach { $0.checklistItems.removeAll { !$0.showTrailer || $0.showVehicle } }
checklistItem.removeAll { $0.count == 0 }

You don't need the extra filter at the end.

Upvotes: 2

Related Questions