Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 按月/年和总和分组数组_Ios_Swift - Fatal编程技术网

Ios 按月/年和总和分组数组

Ios 按月/年和总和分组数组,ios,swift,Ios,Swift,我有一个包含日期和数量的结构。我想把数量按月和按年加起来 我曾想过使用字典(分组,按)但问题是我只能按日期分组,这不是我想要的。基本上,我需要按日期分组,然后执行reduce操作。我不知道如何做到这一点。我总是可以使用蛮力方法在数组中循环并聚合值,但我确信有更好的方法使用map/reduce。有什么想法吗 谢谢你的帮助 struct Transaction { var date = Date() var quantity: Double } 以下是我想要的: 对于该月的数组(已

我有一个包含日期和数量的结构。我想把数量按月和按年加起来

我曾想过使用
字典(分组,按)
但问题是我只能按日期分组,这不是我想要的。基本上,我需要按日期分组,然后执行reduce操作。我不知道如何做到这一点。我总是可以使用蛮力方法在数组中循环并聚合值,但我确信有更好的方法使用map/reduce。有什么想法吗

谢谢你的帮助

struct Transaction {
    var date = Date()
    var quantity: Double
}
以下是我想要的:
对于该月的数组(已排序)或字典(带有
[月:数量之和]

您可以减少交易,并检查每个元素的年和月日期组件是否等于所需的月/年,如果为真,则将其相加,否则返回最后的总数:

let year = 2020
let month = 11
let yearMonth = DateComponents(year: year, month: month)
let total = transactions.reduce(0) {
    Calendar.current.dateComponents([.year, .month], from: $1.date) == yearMonth ? $0 + $1.quantity : $0
}
如果要筛选交易记录而不是仅求和,请执行以下操作:

let filtered = transactions.filter {
    Calendar.current.dateComponents([.year, .month], from: $0.date) == yearMonth
}
如果您的原始交易未排序,请在筛选后对其进行排序:

.sorted { $0.date < $1.date }
要获取每个月的总数量,请执行以下操作:

extension Date {
    var startOfMonth: Date { Calendar.current.dateComponents([.calendar, .year, .month], from: self).date! }
}

或按月对您的交易进行分组:

let grouped: [[Transaction]] = transactions
    .sorted { $0.date < $1.date }
    .reduce(into: []) {
        if $0.last?.last?.date.startOfMonth == $1.date.startOfMonth {
            $0[$0.indices.last!].append($1)
        } else {
            $0.append([$1])
        }
    }
让分组:[[Transaction]]=事务
.sorted{$0.date<$1.date}
.减少(到:[]){
如果$0.last?.last?.date.startOfMonth==1.date.startOfMonth{
$0[$0.index.last!].追加($1)
}否则{
$0.追加([$1])
}
}

Leo,谢谢你的回复。这适用于特定的月份。有没有一种方法可以得到一个按月求和的数组?一年中的所有月份是什么意思?不仅仅是一年,而是所有的数据。我拥有的数据跨越多年,我希望得到数组中每个月的数量总和。很好!非常感谢。
let monthTotals: [Date: Double] = transactions.reduce(into: [:]) {
    $0[$1.date.startOfMonth, default: 0] +=  $1.quantity
}
let grouped: [[Transaction]] = transactions
    .sorted { $0.date < $1.date }
    .reduce(into: []) {
        if $0.last?.last?.date.startOfMonth == $1.date.startOfMonth {
            $0[$0.indices.last!].append($1)
        } else {
            $0.append([$1])
        }
    }