Swift - 执行分组和条件总和

Posted

技术标签:

【中文标题】Swift - 执行分组和条件总和【英文标题】:Swift - Execute group by and conditional sum 【发布时间】:2021-04-01 15:31:31 【问题描述】:

我想通过方法和条件和执行分组。

喜欢:

    1. date:"22-04-2021", name: "morning", value: 2.5
    2. date:"22-05-2021", name: "morning", value: 3.6
    3. date:"22-04-2021", name: "morning", value: 5.9
    3. date:"22-04-2021", name: "evening", value: 4.9
    5. date:"22-06-2021", name: "evening", value: 2.0

我的最终输出将按日期分组,总和大于 3(值>3)

这是我的代码。我尝试了像分组这样的小部分,但没有满足这个特定组的总和。

struct model 
    var date : String?
    var name : String?
    var value : Double




func test()
    
    var arrData = [model]()
    
    arrData.append(model(date: "22-04-2021", name: "morning", value: 2.5))
    arrData.append(model(date: "22-05-2021", name: "morning", value: 3.6))
    arrData.append(model(date: "22-04-2021", name: "evening", value: 5.9))
    arrData.append(model(date: "22-04-2021", name: "evening", value: 4.9))
    arrData.append(model(date: "22-06-2021", name: "evening", value: 2.0))

    let categorieNames = Array(Set(arrData.map($0.date)))
    var arrResult:[[model]] = []
    for i in 0..<categorieNames.count 

        let categories :  [model] = arrData.filter( $0.value > 3 && $0.date == categorieNames[i] )
 
        arrResult.append(categories)
    

print(arrResult)
//            output like
//
//            [
//                ["22-04-2021", name: "morning", value: 2.5,
//                 "22-04-2021", name: "evening", value: 5.9,
//                 "22-04-2021", name: "evening", value: 4.9
//                ]
//
//                ["22-05-2021", name: "morning", value: 3.6],
//
//                ["22-06-2021", name: "evening", value: 2.0]
//            ]


现在我想通过应用大于 3 的条件值来对所有组元素求和。

最终结果会是这样的

[ "22-04-2021", name: "morning", value: 10.8,
  "22-05-2021", name: "morning", value: 3.6
]

【问题讨论】:

name的逻辑是什么?在22-04-2021 组中有两个不同的名称。 你怎么“concat”"22-04-2021", name: "morning", value: 2.5, "22-04-2021", name: "evening", value: 5.9,"22-04-2021", name: "evening", value: 4.9,我知道总和,日期是一样的,但是name呢? 这个名字没有逻辑。我将在数据表示中使用 name 属性到视图中 @vadian。这个名字没有逻辑。我将在数据表示中使用 name 属性到视图中 【参考方案1】:

如果我们忽略名称,您可以使用 Dictionary(grouping:by:) 按日期分组,然后使用 mapValues 来计算总和。值 > 3 的过滤实际上是在创建字典时首先完成的

let result = Dictionary(grouping: arrData.filter( $0.value > 3), by:  $0.date )
   .mapValues( $0.map(\.value).reduce(0, +))

【讨论】:

谢谢。这个答案部分有助于解决。【参考方案2】:

首先用大写名称和非可选(常量)成员声明结构

struct Model 
    let date : String
    let name : String
    let value : Double

根据 Joakim Danielson 的回答首先将 group 数组添加到字典中,然后删除带有 value 的项目

let grouped = Dictionary(grouping: arrData.filter $0.value > 3, by:  $0.date )
// -> ["22-04-2021": [Model(date: "22-04-2021", name: "evening", value: 5.9),        
//                    Model(date: "22-04-2021", name: "evening", value: 4.9)], 
//     "22-05-2021": [Model(date: "22-05-2021", name: "morning", value: 3.6)]]

然后将map 字典添加到一个数组中,创建新的Model 实例并对值求和

let result = grouped.map  item -> Model in
    let v = item.value.map$0.value.reduce(0.0, +)
    return Model(date: item.key, name: item.value.first!.name, value: v)

// -> [Model(date: "22-04-2021", name: "evening", value: 10.8), Model(date: "22-05-2021", name: "morning", value: 3.6)]

【讨论】:

以上是关于Swift - 执行分组和条件总和的主要内容,如果未能解决你的问题,请参考以下文章

熊猫按时间和分组滚动条件总和

如何根据不同的分组条件得到两个数量列的总和?

相邻行熊猫的分组条件总和

使用条件和“分组依据”使用“分组依据”计算的计数记录总和

如何对 Solr 中的多个字段执行嵌套聚合?

如何在 Swift 中获取表格视图单元格数据的总和?