Эффективный и чистый способ заполнения массива словаря в табличном представлении - PullRequest
0 голосов
/ 19 ноября 2018

Может кто-нибудь сказать, чистый и эффективный способ заполнения 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 ]

0 голосов
/ 19 ноября 2018

Попробуйте, используя struct:

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

}
0 голосов
/ 19 ноября 2018

Попробуйте эту игровую площадку:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...