【发布时间】:2016-07-16 11:36:54
【问题描述】:
我有一个数组,var hoursPlayed = String 它们在 tableView 中并且都是数字,我如何将该数组中的数字相加以获得平均播放小时数??????在 Swift 2 中
【问题讨论】:
我有一个数组,var hoursPlayed = String 它们在 tableView 中并且都是数字,我如何将该数组中的数字相加以获得平均播放小时数??????在 Swift 2 中
【问题讨论】:
你可以使用 reduce:
let sum= hoursPlayed.reduce(0.0,combine:{$0+Float($1)!})
基本上,您正在遍历数组并累积所有值。由于它是一个字符串数组,为简单起见,我强制解包为浮点数,但您必须检查可选项。 reduce 函数将闭包作为带有 2 个参数的参数。美元符号表示取第一个和第二个并将它们相加。
现在您可以轻松地除以数组中的元素数量以获得平均值。
如果您在 objC 世界中,最好使用键值编码和 @avg 运算符。
[UPDATE]
正如 Darko 发布的那样,第一个版本无法编译。错误是将第一个参数转换为浮点数,因为 reduce 采用初始值,我将其设置为 Float,无需进一步转换。
【讨论】:
let array = ["10.0", "30.0"]
if array.count > 0 {
let average = array.reduce(0.0, combine: {$0 + (Double($1) ?? 0.0)}) / Double(array.count)
print(average) // 20.0
}
$0 不需要转换,因为它保证它始终是 Double。 $0 是从初始值推断出来的,声明为 0.0: Double。
必须检查array.count 以防止除以 0。
【讨论】:
?? 比强制展开要好得多。做得很好。 (不过,注释应更改为 20.0,因为您正确生成了 Double 而不是 String。)
我会使用flatMap 的组合将字符串转换为双精度,并使用reduce 将它们相加:
let doubles = array.flatMap { Double($0) }
let average = doubles.reduce(0.0, combine:+) / Double(doubles.count)
使用flatMap 可以保护您免受数组中无法转换为Double 的条目的影响,如果您知道它们都可以转换,您可以将其简化为:
let average = array.map({ Double($0)! }) / Double(array.count)
最后一个选择是使用平均函数来扩展 Array,如果这看起来像是您将更普遍使用的东西,并将其与 flatMap 和/或 map 结合使用:
protocol ArithmeticType {
static func zero() -> Self
func +(lhs:Self, rhs:Self) -> Self
func -(lhs:Self, rhs:Self) -> Self
func /(lhs:Self, rhs:Self) -> Self
func *(lhs:Self, rhs:Self) -> Self
init(_ number:Int)
}
extension Double : ArithmeticType {
static func zero() -> Double {
return 0.0
}
}
extension Array where Element : ArithmeticType {
func average() -> Element {
return reduce(Element.zero(), combine:+) / Element(count)
}
}
let avg = array.flatMap { Double($0) }.average()
【讨论】:
修改了 Darko 的方法,考虑了 String 是否可以转换为 Double。对于空数组,它返回 0.0
let array = ["10.0", "31.2", "unknown", ""]
func avg(arr: [String])->Double {
let arr = array.flatMap(Double.init)
var avg = 0.0
if arr.count > 0 {
avg = arr.reduce(0.0, combine: + ) / Double(arr.count)
}
return avg
}
let a = avg(array)
print(a) // 20.6
【讨论】:
flatMap { Double($0) }