使我的函数计算数组Swift的平均值

时间:2015-02-02 22:38:21

标签: arrays function swift swift-playground

我希望我的函数计算我的Double类型数组的平均值。该数组称为“投票”。现在,我有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]

如何在此处调用平均值来获得平均值?

6 个答案:

答案 0 :(得分:91)

您应该使用reduce()方法对数组求和如下:

Xcode 10•Swift 4.2

extension Collection where Element: Numeric {
    /// Returns the total sum of all elements in the array
    var total: Element { return reduce(0, +) }
}

extension Collection where Element: BinaryInteger {
    /// Returns the average of all elements in the array
    var average: Double {
        return isEmpty ? 0 : Double(total) / Double(count)
    }
}

extension Collection where Element: BinaryFloatingPoint {
    /// Returns the average of all elements in the array
    var average: Element {
        return isEmpty ? 0 : total / Element(count)
    }
}

let votes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let votesTotal = votes.total        // 55
let votesAverage = votes.average    // "5.5"

如果您需要使用Decimal类型,Numeric协议扩展属性已涵盖的总和,那么您只需要实现平均属性:

extension Collection where Element == Decimal {
    var average: Decimal {
        return isEmpty ? 0 : total / Decimal(count)
    }
}

答案 1 :(得分:7)

您的代码中存在一些错误:

//You have to set the array-type to Double. Because otherwise Swift thinks that you need an Int-array
var votes:[Double] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

func average(nums: [Double]) -> Double {

    var total = 0.0
    //use the parameter-array instead of the global variable votes
    for vote in nums{

        total += Double(vote)

    }

    let votesTotal = Double(nums.count)
    var average = total/votesTotal
    return average
}

var theAverage = average(votes)

答案 2 :(得分:2)

如果需要,可以使用过滤器进行简单平均(Swift 4.2):

let items: [Double] = [0,10,15]
func average(nums: [Double]) -> Double {
    let sum = nums.reduce((total: 0, elements: 0)) { (sum, item) -> (total: Double, elements: Double) in
        var result = sum
        if item > 0 { // example for filter
            result.total += item
            result.elements += 1
        }

        return result
    }

    return sum.elements > 0 ? sum.total / sum.elements : 0
}
let theAvarage = average(nums: items)

答案 3 :(得分:2)

一小块衬板,使用的是老式的Objective-C KVC(译为Swift):

let average = (votes as NSArray).value(forKeyPath: "@avg.floatValue")

您也可以得到总和:

let sum = (votes as NSArray).value(forKeyPath: "@sum.floatValue")

关于这个久被遗忘的宝石的更多信息:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/CollectionOperators.html

答案 4 :(得分:1)

Swift 4.2

出于纯粹优雅的目的,我喜欢:

// 1. Calls #3
func average <T> (_ values: T...) -> T where T: FloatingPoint
{
    return sum(values) / T(values.count)
}

我们正在尝试其他基于reduce的不错的操作:

// 2. Unnecessary, but I appreciate variadic params. Also calls #3.
func sum <T> (_ values: T...) -> T where T: FloatingPoint
{
    return sum(values)
}

// 3.
func sum <T> (_ values: [T]) -> T where T: FloatingPoint
{
    return values.reduce(0, +)
}

信用:Adrian Houdart的MathKit,基本上没有变化。


可爱的更新:

我在The Swift Programming Language中发现了以下内容:

  

以下示例为任意长度的数字列表计算算术平均值(也称为平均值):

func arithmeticMean(_ numbers: Double...) -> Double {
   var total: Double = 0
   for number in numbers {
       total += number
   }
   return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers

答案 5 :(得分:0)

我有一组在update函数中创建的信号,为了获得移动平均值,我使用此函数来计算由移动平均值周期定义的窗口内的平均值。由于我的目标是组装包含平均值的新信号集,因此我将丢弃原始信号集中的信号。对于那些希望在更新函数中包含移动平均值的用户(例如在SKScene中),这是一个很好的解决方案。

func movingAvarage(_ period: Int) -> Double? {
  if signalSet.count >= period {
   let window = signalSet.suffix(period)
   let mean = (window.reduce(0, +)) / Double(period)
   signalSet = signalSet.dropLast(period)
   return mean
  }
  return nil
}