使用reduce从对象数组填充[String:[CGFloat]]字典

时间:2019-01-12 10:57:17

标签: ios swift xcode dictionary reduce

我有一个对象数组,每个对象都有一个类别和一个数量,如下所示:

Record(“ Bills”,150.00),Record(“ Groceries”,59.90)等...

我想使用reduce来填充[String:[CGFloat]]字典。

应该是这样的:

[“账单”:[150.00、140.00、200.00],“杂货店”:[59.90、40.00、60.00]]

但是,我不知道如何优雅地实现这一目标。

我尝试过(没有成功):

var dictionary = [String:[CGFloat]]()
dictionary = expenses_week.reduce(into: [:]) { (result, record) in
    result[record.category ?? "", default: 0].append((CGFloat(record.amount)))

以上内容返回错误:“无法为不正确或不明确类型的值添加下标。”

我最近得到的是:

var dictionary = [String:[CGFloat]]()
dictionary = expenses_week.reduce(into: [:]) { (result, record) in
    result[record.category ?? "", default: 0] = [(CGFloat(record.amount))]

那行得通,但显然不能满足我的要求。 :)

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您的代码几乎正确。 dictionary的值类型为[CGFloat],因此下标操作中的默认值必须为空数组,而不是数字0

let dictionary = expenses_week.reduce(into: [:]) { (result, record) in
    result[record.category ?? "", default: []].append(CGFloat(record.amount))
}

您还可以考虑将类型转换为CGFloat,然后结果的类型为[String : [Double]]

顺便说一句,替代方法(但不一定是更有效的方法)将会

let dictionary = Dictionary(expenses_week.map { ($0.category ?? "", [$0.amount]) },
                            uniquingKeysWith: +)

let dictionary = Dictionary(grouping: expenses_week, by: { $0.category ?? "" })
    .mapValues { $0.map { $0.amount } }

答案 1 :(得分:1)

struct Record {
    let category: String
    let amount: NSNumber
}

let records = [
    Record(category: "Bills", amount: 150.00),
    Record(category: "Bills", amount: 140.00),
    Record(category: "Bills", amount: 200.00),
    Record(category: "Groceries", amount: 59.90),
    Record(category: "Groceries", amount: 40.00),
    Record(category: "Groceries", amount: 60.00),
]

let dictionary = records.reduce(into: [String:[NSNumber]](), {
    $0[$1.category] = $0[$1.category] ?? []
    $0[$1.category]?.append($1.amount)
})

print(dictionary)