我想让我的函数计算双类型数组的平均值.这个数组被称为"投票".现在,我有10个数字.

当我调用average function来获得数组投票的平均值时,它不起作用.

这是我的代码:

var votes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

func average(nums: Double...) -> Double {
    var total = 0.0
    for vote in votes {
        total += vote
    }
    let votesTotal = Double(votes.count)
    var average = total/votesTotal
    return average
}

average[votes]

我如何在这里调用平均值来获得平均值?

推荐答案

您应该使用reduce方法对序列元素求和,如下所示:

Xcode Xcode 10.2+ • Swift 5 or later

extension Sequence where Element: AdditiveArithmetic {
    /// Returns the total sum of all elements in the sequence
    func sum() -> Element { reduce(.zero, +) }
}

extension Collection where Element: BinaryInteger {
    /// Returns the average of all elements in the array
    func average() -> Element { isEmpty ? .zero : sum() / Element(count) }
    /// Returns the average of all elements in the array as Floating Point type
    func average<T: FloatingPoint>() -> T { isEmpty ? .zero : T(sum()) / T(count) }
}

extension Collection where Element: BinaryFloatingPoint {
    /// Returns the average of all elements in the array
    func average() -> Element { isEmpty ? .zero : sum() / Element(count) }
}

let votes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let votesTotal = votes.sum()                       // 55
let votesAverage = votes.average()                 // 5
let votesDoubleAverage: Double = votes.average()   // 5.5

如果您需要处理Decimal种类型,那么AdditiveArithmetic协议扩展方法已经涵盖了它的总和,因此您只需要实现平均值:

extension Collection where Element == Decimal {
    func average() -> Decimal { isEmpty ? .zero : sum() / Decimal(count) }
}


如果需要对自定义 struct 的某个属性求和,我们可以扩展Sequence并创建一个方法,该方法将KeyPath作为参数来计算其和:

extension Sequence  {
    func sum<T: AdditiveArithmetic>(_ predicate: (Element) -> T) -> T {
        reduce(.zero) { $0 + predicate($1) }
    }
}

用法:

struct User {
    let name: String
    let age: Int
}

let users: [User] = [
    .init(name: "Steve", age: 45),
    .init(name: "Tim", age: 50)]

let ageSum = users.sum(\.age) // 95

并扩展集合以计算其平均值:

extension Collection {
    func average<T: BinaryInteger>(_ predicate: (Element) -> T) -> T {
        sum(predicate) / T(count)
    }
    func average<T: BinaryInteger, F: BinaryFloatingPoint>(_ predicate: (Element) -> T) -> F {
        F(sum(predicate)) / F(count)
    }
    func average<T: BinaryFloatingPoint>(_ predicate: (Element) -> T) -> T {
        sum(predicate) / T(count)
    }
    func average(_ predicate: (Element) -> Decimal) -> Decimal {
        sum(predicate) / Decimal(count)
    }
}

用法:

let ageAvg = users.average(\.age)                 // 47
let ageAvgDouble: Double = users.average(\.age)   // 47.5

Swift相关问答推荐

在解码字符串时需要帮助.

阴影动画的动画不流畅

RealityKit(VisionOS)中的PhysicBodyComponent和DragGesture

如何在SWIFT中使用DiscardingTaskGroup获得任务结果

Swift-Can无法在AudioKit中找出简单的麦克风效果-文件链

从SwiftUI使用UIPageView时,同一页面连续显示两次的问题

在Swift中,将秒设置为0也等于将1添加到分钟

可选,类似于自定义类型的初始化

有没有办法让文本字段以不同的 colored颜色 显示而不影响半透明背景?

RealityKit - 从中心zoom 模型

Swift并发:为什么不在其他后台线程上执行任务

使 Swift 并发中的任务串行运行

调用从 SwiftUI 视图传递到 PageViewController.Coordinator 的函数

如何在 SwiftUI 中通过按钮点击一次为一个更改设置动画?

macOS 守护进程应该由Command Line ToolXcode 模板制作吗?

Xcode 13.3 将函数调用更改为属性访问

swift 如何从 Int 转换?到字符串

如何从元组数组创建字典?

强制打开已在同一行代码中 Select 性访问的变量是否安全?

iPhone 纵向和 iPad 横向的通用应用程序