Inderpal Singh
Inderpal Singh

Reputation: 1269

Create tableView section headers corresponding to month

My NSMutableArray and I want to create the Single object corresponding to months.

My JSON objects are below where you can see key name Month

(
        {
        day = 27;
        month = "Feb 2018";
        title = HOLIDAY;
    },
        {
        day = 28;
        month = "Feb 2018";
        title = PRESENT;
    },
        {
        day = 1;
        month = "MAR 2018";
        title = ABSENT;
    },
        {
        day = 2;
        month = "MAR 2018";
        title = ABSENT;
    }
)

Code for saving objects, I have another mutable array where I try to save objects corresponding to months.

let array = NSMutableArray()
        var index = Int()
        index = 0
        finalArray.removeAll()
        for i in 0 ..< jsonArray.count{
            if (jsonArray[index] as AnyObject).value(forKey: "month") as! String == (jsonArray[i] as AnyObject).value(forKey: "month") as! String{
                array.add(jsonArray[i])
            }else{
                finalArray.append(array)
                array.removeAllObjects()
                array.add(jsonArray[i])
                index = i
            }
        }
        finalArray.append(array)
        print(finalArray) 

Output: Duplicates objects

[ (
            {
            day = 1;
            month = "Mar 2018";
            title = ABSENT;
        },
            {
            day = 2;
            month = "MAR 2018";
            title = ABSENT;
        }),
        ({
            day = 1;
            month = "MAR 2018";
            title = ABSENT;
        },
            {
            day = 2;
            month = "MAR 2018";
            title = ABSENT;
        }
    )]

I want this Output after filter JSON:

[ (
            {
            day = 27;
            month = "FEB 2018";
            title = ABSENT;
        },
            {
            day = 28;
            month = "FEB 2018";
            title = ABSENT;
        }),
        ({
            day = 1;
            month = "MAR 2018";
            title = ABSENT;
        },
            {
            day = 2;
            month = "MAR 2018";
            title = ABSENT;
        }
    )]

Upvotes: 0

Views: 458

Answers (1)

Bista
Bista

Reputation: 7893

I think the code will be self explanatory and can't get easier than this:

class ViewController: UIViewController {

    @IBOutlet var table: UITableView!

    var jsonArray: [[String:Any]] = [
        ["day": 27, "month": "Feb 2018", "title": "HOLIDAY"],
        ["day": 28, "month": "Feb 2018", "title": "PRESENT"],
        ["day": 1, "month": "MAR 2018", "title": "ABSENT"],
        ["day": 2, "month": "MAR 2018", "title": "ABSENT"]
    ]


    var groupedArray = [[String: Any]]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        table.register(UITableViewCell.self, forCellReuseIdentifier: "DataCell")

        //Extract Months
        let months: [String] = Array(Set(jsonArray.map({$0["month"] as! String})))

        print(months)


        //Sort month by name
        let sortedMonths = months.sorted { (month1, month2) -> Bool in
            let formatter = DateFormatter()
            formatter.dateFormat = "MMM yyyy"

            let date1 = formatter.date(from: month1)
            let date2 = formatter.date(from: month2)

            return date1!.compare(date2!) == .orderedAscending
        }

        print(sortedMonths)


        //group data according to months

        for month in sortedMonths {
            var groupedByMonth = [String: Any]()
            let filteredByMonth = jsonArray.filter({ ($0["month"] as! String) == month })

            groupedByMonth["month"] = month
            groupedByMonth["data"]  = filteredByMonth

            groupedArray.append(groupedByMonth)
        }

        print(groupedArray)
    }
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func numberOfSections(in tableView: UITableView) -> Int {
        return groupedArray.count
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let groupedData = groupedArray[section]
        return groupedData["month"] as? String ?? "Section Title"
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let groupedData = groupedArray[section]
        let data: [[String: Any]] = groupedData["data"] as? [[String: Any]] ?? [[:]]
        return data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "DataCell", for: indexPath)

        let groupedData = groupedArray[indexPath.section]
        let data: [[String: Any]] = groupedData["data"] as! [[String: Any]]
        let rowData = data[indexPath.row]

        cell.textLabel?.text = rowData["title"] as! String

        return cell
    }
}

Upvotes: 1

Related Questions