如何将数组中的相同元素分组并在Swift中求和?

时间:2017-11-24 03:36:52

标签: arrays swift

如何将重复的类别元素过滤到不同的数组并计算其数量?

这是格式,记录来自核心数据。

var record = [Record]()

[<Record:...; data: {accountbook = "MyBook";
                     amount = "10.50";
                     category = "A";
                     id = 1; 
},<Record:...; data: {accountbook = "MyBook";
                     amount = "5.50";
                     category = "B";
                     id = 2;
},<Record:...; data: {accountbook = "MyBook";
                     amount = "4.50";
                     category = "B";
                     id = 3;
}]

我想要什么

var category = ["A", "B"] //success
var total = [10.50, 10.00]

这是我为查找类别所做的工作,但它有效,但如何对同一类别进行分组并总计?

var category =[String]()
for categoryObject in record{
    if let categoryItem = categoryObject.category{
        category.append(categoryItem)
    }
}

//I tried this code to group the same category but fail. 

let result = Set(record).map{ category in return record.filter{$0 == category} }

另一种方式是这样的。但是,如果我有A-Z类别?它将有很长的代码..有没有办法可以检测到相同的值并将其拆分为不同的数组,以便我可以按类别加总。

categoryFilter = record.filter { $0.category!.contains("A") }

3 个答案:

答案 0 :(得分:0)

首先按类别this

对您的记录对象进行分组
extension Sequence {
    func group<GroupingType: Hashable>(by key: (Iterator.Element) -> GroupingType) -> [[Iterator.Element]] {
        var groups: [GroupingType: [Iterator.Element]] = [:]
        var groupsOrder: [GroupingType] = []
        forEach { element in
            let key = key(element)
            if case nil = groups[key]?.append(element) {
                groups[key] = [element]
                groupsOrder.append(key)
            }
        }
        return groupsOrder.map { groups[$0]! }
    }
}

然后,您将根据此类

获得不同的数组
var records : [Record] = []// your objects
let distinctRecords = records.group(by: {$0. category})

现在您可以使用reduce来计算该类别的值之和

for items in distinctRecords{
    let sum = items.reduce(0.0){$0.0 + $1. amount ?? 0.0}// assuming you have float values in your amount
    print(items)// do whatever you want to do with your distinct array
    print(" \(sum)")
}

答案 1 :(得分:0)

@Wan Jern我写了一段代码,你可以试试这个。希望它会起作用。

import UIKit

class TrashCan: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var trashView: UITableView!

var MemoData = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    if let MemoData = UserDefaults.standard.string(forKey: "MemoData") {
        print(MemoData)
    }
    // Do any additional setup after loading the view.
}

// MARK : Table
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    MemoData = UserDefaults.standard.object(forKey: "MemoData") as? [String] ?? [String]()
    return MemoData.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let Cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TrashCell

    MemoData = UserDefaults.standard.object(forKey: "MemoData") as? [String] ?? [String]()
    Cell.TitleLabel.text = MemoData[indexPath.row]

    return Cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let MemoNumber = indexPath.row
    UserDefaults.standard.set(MemoNumber, forKey: "MemoNumber")

    self.performSegue(withIdentifier: "ToRecord", sender: self)
}
// Table_End

@IBAction func trashList(_ sender: Any) {
    let alertController = UIAlertController(title: "Hello", message: "What do you want to do?", preferredStyle: .actionSheet)

    let moveAction = UIAlertAction(title: "Move", style: .destructive) { (action: UIAlertAction) in

    } // Main으로 복원

    let deleteAction = UIAlertAction(title: "Delete", style: .destructive) { (action: UIAlertAction) in

    } // 완전삭제

    let cancelButtonAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel)


    alertController.addAction(moveAction)
    alertController.addAction(deleteAction)
    alertController.addAction(cancelButtonAction)
    present(alertController, animated: true, completion: nil)
}

}

答案 2 :(得分:0)

Records设为Hashable with&#34; category&#34;作为存根函数中的唯一

struct Record: Hashable {

    var accountbook = ""
    var category = ""
    var amount = 0.0
    // added from stubs of Hashable
    var hashValue: Int { return category.hashValue }

    static func ==(lhs: Record, rhs: Record) -> Bool {
        return lhs.category == rhs.category
    }
}

然后过滤唯一类别

let categories = Set(record).map { $0.category }
print(categories) // ["B", "A"]

并对每个类别进行总结

let totals = categories.map { c in
    record.filter { $0.category == c }.map{ $0.amount }.reduce(0, +)
}
print(totals) // get the sums as [10.0, 10.5]