【问题标题】:How to add numbers in a string array? Swift如何在字符串数组中添加数字?迅速
【发布时间】:2016-07-16 11:36:54
【问题描述】:

我有一个数组,var hoursPlayed = String 它们在 tableView 中并且都是数字,我如何将该数组中的数字相加以获得平均播放小时数??????在 Swift 2 中

【问题讨论】:

标签: ios arrays swift swift2


【解决方案1】:

你可以使用 reduce:

let sum= hoursPlayed.reduce(0.0,combine:{$0+Float($1)!})

基本上,您正在遍历数组并累积所有值。由于它是一个字符串数组,为简单起见,我强制解包为浮点数,但您必须检查可选项。 reduce 函数将闭包作为带有 2 个参数的参数。美元符号表示取第一个和第二个并将它们相加。 现在您可以轻松地除以数组中的元素数量以获得平均值。
如果您在 objC 世界中,最好使用键值编码和 @avg 运算符。
[UPDATE]
正如 Darko 发布的那样,第一个版本无法编译。错误是将第一个参数转换为浮点数,因为 reduce 采用初始值,我将其设置为 Float,无需进一步转换。

【讨论】:

  • 基本思路当然是对的,但是编译不了。
  • 对不起,我在 iPad 上写作,我什么时候在办公​​室编辑
【解决方案2】:
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。

【讨论】:

  • 这是对惯用 Swift 的一个很好的说明。使用?? 比强制展开要好得多。做得很好。 (不过,注释应更改为 20.0,因为您正确生成了 Double 而不是 String。)
【解决方案3】:

我会使用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()

【讨论】:

  • flatMap 版本看起来非常干净和直观。唯一的缺点 - 它需要在数组上迭代两次。但在大多数情况下的应用程序开发中,这可以忽略不计,我更喜欢可读性而不是性能。 +1
  • 至少有一个版本使用lazy,只做一次迭代,避免创建多个数组。
【解决方案4】:

修改了 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.init) 吗?
  • 为什么不这样呢? flatMap { Double($0) }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 2017-04-23
相关资源
最近更新 更多