【问题标题】:Using reduce to populate a [String : [CGFloat]] dictionary from an object array使用 reduce 从对象数组中填充 [String : [CGFloat]] 字典
【发布时间】:2019-06-07 02:33:48
【问题描述】:

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

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)))

上面返回错误:“Cannot subscript a value of wrong or ambiguous type.”

我得到的最接近的是:

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

这行得通,但显然它并没有达到我想要的效果。 :)

非常感谢您的帮助。

【问题讨论】:

    标签: ios swift xcode dictionary reduce


    【解决方案1】:

    您的代码几乎是正确的。 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 } }
    

    【讨论】:

      【解决方案2】:
      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)
      

      【讨论】:

      • 太棒了!谢谢你,卡拉姆!
      猜你喜欢
      • 2015-03-08
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      相关资源
      最近更新 更多