让我的函数计算数组的平均值 Swift
Making my function calculate average of array Swift
我想让我的函数计算我的 Double 类型数组的平均值。该数组称为 "votes"。现在,我有 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]
这里要怎么调用平均值才能得到平均值?
您的代码有一些错误:
//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)
您应该使用 reduce
方法对序列元素求和,如下所示:
Xcode Xcode 10.2+ • Swift 5 或更高
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) }
}
如果您需要对自定义结构的某个 属性 求和,我们可以扩展 Sequence
并创建一个以 KeyPath 作为参数来计算其总和的方法:
extension Sequence {
func sum<T: AdditiveArithmetic>(_ predicate: (Element) -> T) -> T {
reduce(.zero) { [=15=] + predicate() }
}
}
用法:
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 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)
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 中找到以下内容:
The example below calculates the arithmetic mean (also known as the average) for a list of numbers of any length:
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
一个小衬里,使用老式的 Objective-C KVC 翻译成 Swift:
let average = (votes as NSArray).value(forKeyPath: "@avg.floatValue")
你还可以求和:
let sum = (votes as NSArray).value(forKeyPath: "@sum.floatValue")
关于这个早已被遗忘的 gem 的更多信息:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/CollectionOperators.html
我有一组在更新函数中创建的信号,为了获得移动平均线,我使用此函数计算由移动平均线周期定义的 window 内的平均值。由于我的目标是 assemble 一组包含平均值的新信号,因此我将丢弃原始信号集中的信号。对于那些想要在更新函数中使用移动平均线的人来说,这是一个很好的解决方案,例如在 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
}
我想让我的函数计算我的 Double 类型数组的平均值。该数组称为 "votes"。现在,我有 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]
这里要怎么调用平均值才能得到平均值?
您的代码有一些错误:
//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)
您应该使用 reduce
方法对序列元素求和,如下所示:
Xcode Xcode 10.2+ • Swift 5 或更高
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) }
}
如果您需要对自定义结构的某个 属性 求和,我们可以扩展 Sequence
并创建一个以 KeyPath 作为参数来计算其总和的方法:
extension Sequence {
func sum<T: AdditiveArithmetic>(_ predicate: (Element) -> T) -> T {
reduce(.zero) { [=15=] + predicate() }
}
}
用法:
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 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)
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 中找到以下内容:
The example below calculates the arithmetic mean (also known as the average) for a list of numbers of any length:
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
一个小衬里,使用老式的 Objective-C KVC 翻译成 Swift:
let average = (votes as NSArray).value(forKeyPath: "@avg.floatValue")
你还可以求和:
let sum = (votes as NSArray).value(forKeyPath: "@sum.floatValue")
关于这个早已被遗忘的 gem 的更多信息:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/CollectionOperators.html
我有一组在更新函数中创建的信号,为了获得移动平均线,我使用此函数计算由移动平均线周期定义的 window 内的平均值。由于我的目标是 assemble 一组包含平均值的新信号,因此我将丢弃原始信号集中的信号。对于那些想要在更新函数中使用移动平均线的人来说,这是一个很好的解决方案,例如在 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
}