gpt4 book ai didi

swift - 如何在 Swift 中仅对数组的一部分求和?

转载 作者:可可西里 更新时间:2023-11-01 01:37:42 26 4
gpt4 key购买 nike

我目前正尝试在 Swift 中构建我的第一个应用程序,并希望找到一个数组的一部分相对于当月的总和。这是我的代码:

struct Hour {
var date: String?
var time: String?

init(date: String?, time: String?) {
self.date = date
self.time = time
}
}


let hoursData = [
Hour(date: "Nov 29, 2015", time: "7"),
Hour(date: "Dec 12, 2015", time: "7"),
Hour(date: "Dec 14, 2015", time: "7"),
Hour(date: "Dec 25, 2015", time: "7") ]

我想知道如何制作一个包含当月 time 数据总和的变量?或者任何一个月?非常感谢你们能提供的任何帮助。

最佳答案

首先我会重写你的结构,
这两个属性都可以是不可变的。

我使用 NSDate 代替日期字符串,并使用 double 来表示持续时间

struct Hour {
let date: NSDate
let duration: Double

init(date: NSDate, duration: Double) {
self.date = date
self.duration = duration
}
}

我创造了这样的时间

let hoursData = [
Hour(date: { let c = NSDateComponents(); c.day = 29; c.month = 11; c.year = 2015; return NSCalendar.currentCalendar().dateFromComponents(c)!}(), duration: 7),
Hour(date: { let c = NSDateComponents(); c.day = 12; c.month = 12; c.year = 2015; return NSCalendar.currentCalendar().dateFromComponents(c)!}(), duration: 7),
Hour(date: { let c = NSDateComponents(); c.day = 14; c.month = 12; c.year = 2015; return NSCalendar.currentCalendar().dateFromComponents(c)!}(), duration: 7),
Hour(date: { let c = NSDateComponents(); c.day = 15; c.month = 12; c.year = 2015; return NSCalendar.currentCalendar().dateFromComponents(c)!}(), duration: 7)]

如果你对这个语法感到疑惑:我使用隐式未命名闭包来创建 NSDate 参数

现在我过滤月份和年份,并使用 reduce 方法对过滤后的对象求和

let today = NSDate()
let totalDuration = hoursData.filter{
let objectsComps = NSCalendar.currentCalendar().components([.Month, .Year], fromDate: $0.date)
let todaysComps = NSCalendar.currentCalendar().components([.Month, .Year], fromDate: today)
return objectsComps.month == todaysComps.month && objectsComps.year == todaysComps.year
}.reduce(0) { (duration, hour) -> Double in
duration + hour.duration
}

虽然这是一个很好的答案,但我想指出 Rob 的答案有一个小缺陷:Hour 结构隐藏了日期字符串需要某种格式的依赖项。这违反了 Dependency Inversion Principle , SOLID Principles 中的 D .但这很容易解决。

在创建 Hour 实例时只需传入日期格式化程序即可。

struct Hour {
let date: NSDate
let duration: Double

init(date: NSDate, duration: Double) {
self.date = date
self.duration = duration
}

init (dateFormatter:NSDateFormatter, dateString:String, duration:Double) {
self.init(date: dateFormatter.dateFromString(dateString)!, duration:duration)
}
}

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM d, y"

let hoursData = [
Hour(dateFormatter: dateFormatter, dateString: "Nov 29, 2015", duration: 7),
Hour(dateFormatter: dateFormatter, dateString: "Dec 12, 2015", duration: 7),
Hour(dateFormatter: dateFormatter, dateString: "Dec 14, 2015", duration: 7),
Hour(dateFormatter: dateFormatter, dateString: "Dec 25, 2015", duration: 7),
Hour(dateFormatter: dateFormatter, dateString: "Dec 25, 2017", duration: 7)
]

现在使用Hour 的人可以根据需要定义格式,这可能对本地化应用程序有帮助。

过滤和减少保持不变。


但现在我们有一个新问题:NSDateformatter 的 dateFromString() 可能返回 nil。目前我们用 ! 强制解包,但这在生产应用中可能不好。

我们应该允许适当的错误处理,通过允许便利的 init 抛出错误

enum HourError: ErrorType {
case InvalidDate
}

struct Hour {

let date: NSDate
let duration: Double

init(date: NSDate, duration: Double) {
self.date = date
self.duration = duration
}

init (dateFormatter:NSDateFormatter, dateString:String, duration:Double) throws {
let date = dateFormatter.dateFromString(dateString)
guard date != nil else { throw HourError.InvalidDate}
self.init(date: date!, duration:duration)
}
}

如果我们像这样使用它

do {
let now = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM d, y"

let hoursData = [
try Hour(dateFormatter: dateFormatter, dateString: "Nov 29, 2015", duration: 7),
try Hour(dateFormatter: dateFormatter, dateString: "Dec 12, 2015", duration: 7),
try Hour(dateFormatter: dateFormatter, dateString: "Dec 14, 2015", duration: 7),
try Hour(dateFormatter: dateFormatter, dateString: "Dec 25, 2015", duration: 7),
/*⛈*/ try Hour(dateFormatter: dateFormatter, dateString: " 25, 2017", duration: 7)
]



let totalDuration = hoursData.filter{
let objectsComps = NSCalendar.currentCalendar().components([.Month, .Year], fromDate: $0.date)
let todaysComps = NSCalendar.currentCalendar().components([.Month, .Year], fromDate: now)
return objectsComps.month == todaysComps.month && objectsComps.year == todaysComps.year
}.reduce(0) {
$0 + $1.duration
}
print(totalDuration)
} catch HourError.InvalidDate{
print("one or more datestrings must be wrong")
}

错误将被捕获。


full code

关于swift - 如何在 Swift 中仅对数组的一部分求和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34425881/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com