如何将基于Date项的数组数据分组到字典中

时间:2017-02-15 17:58:50

标签: arrays swift dictionary

我有一组Item个对象:

struct Item {
   let date: Date
   let amount: Double
}

如何将这些项目组合成一个字典,其中Date为关键字,并且在Swift 3中该日期为amount的总和?

以下是一个例子:

let data = [Item(date:"2017.02.15", amount: 25), 
            Item(date:"2017.02.14", amount: 50), 
            Item(date:"2017.02.11", amount: 35), 
            Item(date:"2017.02.15", amount: 15)]

结果应该是:

["2017.02.15": 40, "2017.02.14": 50, "2017.02.11": 35]

3 个答案:

答案 0 :(得分:3)

鉴于我们稍微修改了您的示例(使用Date作为data示例),您可以简单地传递struct Item { let date: String let amount: Double } let data = [Item(date: "2017.02.15", amount: 25), Item(date: "2017.02.14", amount: 50), Item(date: "2017.02.11", amount: 35), Item(date: "2017.02.15", amount: 15)] var dict: [String: Double] = [:] for item in data { dict[item.date] = (dict[item.date] ?? 0) + item.amount } print(dict) // ["2017.02.14": 50.0, "2017.02.15": 40.0, "2017.02.11": 35.0] 中的元素并添加(并可选地增加)相应的键字典中的值对。

{{1}}

答案 1 :(得分:2)

我认为这个解决方案可能会更好,因为您的属性$('.myModalViewAddress').on('hidden.bs.modal', function() { $(this).find('auth_form10')[0].reset(); }); 实际上是date

解决方案:

Date

助手方法:

struct Item {
  let date: Date
  let amount: Double
}

var data = [Item(date:createDate(stringDate: "2017.02.15"), amount: 25),
            Item(date:createDate(stringDate: "2017.02.14"), amount: 50),
            Item(date:createDate(stringDate: "2017.02.11"), amount: 35),
            Item(date:createDate(stringDate: "2017.02.15"), amount: 15)]

data = sumAmounts(data)

print(data)
//[
//  Item(date: 2017-02-15 04:00:00 +0000, amount: 40.0),
//  Item(date: 2017-02-14 04:00:00 +0000, amount: 50.0),
//  Item(date: 2017-02-11 04:00:00 +0000, amount: 35.0)
//]

答案 2 :(得分:1)

使用Swift 4,根据您的需要,您可以选择以下解决方案之一来解决您的问题。

#1使用Dictionary subscript(_:default:)

Dictionay有一个名为subscript(_:default:)的下标。 subscript(_:default:)有以下声明:

subscript(key: Dictionary.Key, default defaultValue: @autoclosure () -> Dictionary.Value) -> Dictionary.Value { get set }
  

如果字典不包含给定的键,则使用给定键或指定的默认值访问元素。

以下Playground示例显示了如何使用subscript(_:default:)来解决您的问题:

struct Item {
    let date: String
    let amount: Double
}

let data = [
    Item(date:"2017.02.15", amount: 25),
    Item(date:"2017.02.14", amount: 50),
    Item(date:"2017.02.11", amount: 35),
    Item(date:"2017.02.15", amount: 15)
]

var dictionary = [String: Double]()

for item in data {
    dictionary[item.date, default: 0.0] += item.amount
}

print(dictionary) // ["2017.02.11": 35.0, "2017.02.15": 40.0, "2017.02.14": 50.0]

#2使用Dictionary init(_:uniquingKeysWith:)初始化程序

Dictionay有一个init(_:uniquingKeysWith:)初始化程序。 init(_:uniquingKeysWith:)有以下声明:

init<S>(_ keysAndValues: S, uniquingKeysWith combine: (Value, Value) throws -> Value) rethrows where S : Sequence, S.Element == (Key, Value)
  

使用组合闭包从给定序列中的键值对创建新字典,以确定任何重复键的值。

以下Playground示例显示了如何使用init(_:uniquingKeysWith:)来解决您的问题:

struct Item {
    let date: String
    let amount: Double
}

let data = [
    Item(date:"2017.02.15", amount: 25),
    Item(date:"2017.02.14", amount: 50),
    Item(date:"2017.02.11", amount: 35),
    Item(date:"2017.02.15", amount: 15)
]

let tupleArray = data.map({ ($0.date, $0.amount) })
let dictonary = Dictionary(tupleArray, uniquingKeysWith: { (current, new) in
    current + new
})
//let dictonary = Dictionary(tupleArray, uniquingKeysWith: +) // also works

print(dictonary) // prints ["2017.02.11": 35.0, "2017.02.15": 40.0, "2017.02.14": 50.0]