代码之家  ›  专栏  ›  技术社区  ›  user3310076

表视图中填充数组字典的高效、干净方法

  •  0
  • user3310076  · 技术社区  · 6 年前

    有人能说出用字典数组填充TableView的干净有效的方法吗?我有模型 Sale 其中包含saleAmount、soldby、division和saledate。每个部门可能包含许多销售数据,并希望按每个部门分离销售数据。此外,在TableView标题中,我希望显示部门名称以及特定部门的总销售额。

    class Sale  {
    
        var saleAmount : Double = 0.00 
        var soldBy : String = ""
        var division : String = ""
        var saleDate : Date?
    }
    

    我接收数据并存储在

    var sales : [Sale] = [Sale]()
    

    然后我把数据处理成每一个“部门”的字典

    var salesDict : [String : Sale] = [String : Sale] ()
    func createIndex<Key, Element>(elms:[Element], extractKey:(Element) -> Key) -> [Key:Element] where Key : Hashable {
            return elms.reduce([Key:Element]()) { (dict, elm) -> [Key:Element] in
                var dict = dict
                dict[extractKey(elm)] = elm
                return dict
            }
        }
    
    salesDict = createIndex(elms: sales, extractKey: {$0.division})
    salesSection = salesDict.compactMap(){$0.key} // To store keys
    
    print(saleDict) // ["division1": Clientname.Sale, "division2": Clientname.Sale, "division3": Clientname.Sale, "division4": Clientname.Sale]
    

    并填充TableView

    func numberOfSections(in tableView: UITableView) -> Int {
    
           return salesSection.count
        }
    

    数据填充不正确

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    
            return [salesDict[salesSection[section]]?.soldBy].count
    
        }
    
    
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
                let saleItem = salesDict[salesSection[indexPath.section]]
                let cell = tableView.dequeueReusableCell(withIdentifier: "FoldingCell", for: indexPath) as! SaleHistoryTableViewCell
    
    cell.saleAmountLabel.text = ("\(String(describing: saleItem?.saleAmount))")
        }
    
     func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    
            return salesSection[section]
        }
    
    2 回复  |  直到 6 年前
        1
  •  0
  •   Fabio Felici    6 年前

    试试这个操场:

    import UIKit
    import PlaygroundSupport
    
    class Sale {
        var saleAmount : Double = 0.00
        var soldBy : String = ""
        var division : String = ""
        var saleDate : Date?
    
        init(saleAmount : Double = 0.0, soldBy : String = "" , division : String = "", saleDate : Date? = nil) {
            self.saleAmount = saleAmount
            self.soldBy = soldBy
            self.division = division
            self.saleDate = saleDate
        }
    }
    
    class VC: UITableViewController {
    
        var salesGroupedByDivision: [String: [Sale]]!
    
        init() {
            super.init(style: .grouped)
            self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
            let sales = [
                Sale(saleAmount: 1.0, division: "1"),
                Sale(saleAmount: 2.0, division: "1"),
                Sale(saleAmount: 3.0, division: "2")
            ]
            salesGroupedByDivision = Dictionary(grouping: sales, by: { $0.division })
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError()
        }
    
        override func numberOfSections(in tableView: UITableView) -> Int {
            return salesGroupedByDivision.keys.count
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            let division = Array(salesGroupedByDivision.keys)[section]
            return salesGroupedByDivision[division]?.count ?? 0
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
            let division = Array(salesGroupedByDivision.keys)[indexPath.section]
            let sale = salesGroupedByDivision[division]?[indexPath.row]
            cell.textLabel?.text = "\(sale?.saleAmount)"
            return cell
        }
    
        override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
            let division = Array(salesGroupedByDivision.keys)[section]
            return "\(division) \(salesGroupedByDivision[division]?.reduce(0, { $0 + $1.saleAmount }) ?? 0)"
        }
    }
    
    let vc = VC()
    
    PlaygroundPage.current.needsIndefiniteExecution = true
    PlaygroundPage.current.liveView = vc
    
        2
  •  0
  •   Suhail    6 年前

    尝试使用结构:

    struct Sale {
    var saleAmount : Double = 0.00 
    var soldBy : String = ""
    var division : String = ""
    var saleDate : Date?
    

    }

    类ViewController:uiViewController{

    var arrayOfSaleData = [Sale]()
    
    override func viewDidLoad(){
    
        loadDataIntoArray()
    }
    
    func loadDataIntoArray(){
    
    
         let mainSaleAmount = saleAmountData as? Double ?? 0
         let sold = soldData as? String ?? ""
         let div = divisionData as? String ?? ""
         let mainSaleDate = saleDateData as! Date
    
          //populate your struct with the received data                 
          let allData = Sale(saleAmount: mainSaleAmount , soldBy: sold , division: div , saleDate: mainSaleDate )
    
          self.arrayOfSaleData(allData)
    
          DispatchQueue.main.async {
          tabelView.reloadData()
    
          }
    
     }
    

    }

    extension ViewController : UITableViewDataSource, UITableViewDelegate{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int)
             -> Int {
    
            return arrayOfSaleData.count
    
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    
            let cell = Bundle.main.loadNibNamed("YourTableViewCell", owner: self, options: nil)?.first as! YourTableViewCell
            //Here you can assign your table view cell elements with data from your struct array
            cell.saleAmountLabel.text = arrayOfSaleData[indexPath.row]. saleAmount
    
            return cell
    
    }