0

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 !

0

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I can't use the second removeAll because I get the error Cannot convert value of type '()' to closure result type 'Bool'. If I use checklistItem.removeAll {$0.checklistItems.filter{!$0.showVehicle && $0.showTrailer}.count != 0} then I don't get any error but is not working the remove. If I use checklistItem.removeAll {$0.checklistItems.removeAll{!$0.showVehicle && $0.showTrailer}} I get that error.
I tried your solution but for some reasons after filtering I get every time the same count. Here is a printscreen: imgur.com/a/KwFACXd
@Flo You've got the wrong condition. It should be !$0.showTrailer || $0.showVehicle. With "||". NOT (showTrailer AND NOT showVehicle) expands to NOT showTrailer OR showVehicle because of DeMorgan's laws.

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.