arrays - initialize - swift array filter
Hacer que mi funciĆ³n calcule el promedio de la matriz Swift (5)
Swift 4.2
Por pura simplicidad elegante, me encanta:
// 1. Calls #3
func average <T> (_ values: T...) -> T where T: FloatingPoint
{
return sum(values) / T(values.count)
}
Mientras estamos en ello, otras buenas operaciones basadas en la
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, +)
}
Crédito: MathKit Adrian Houdart, prácticamente sin cambios.
Linda actualización:Encontré lo siguiente en The Swift Programming Language :
El siguiente ejemplo calcula la media aritmética (también conocida como el promedio) para una lista de números de cualquier longitud:
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
Quiero que mi función calcule el promedio de mi matriz de tipo Doble. La matriz se llama "votos". Por ahora, tengo 10 números.
Cuando llamo a la
average function
para obtener el promedio de los votos de la matriz, no funciona.
Aquí está mi código:
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]
¿Cómo llamo al promedio aquí para obtener el promedio?
Avarage simple con filtro si es necesario (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)
Debe usar el método reduce () para sumar su matriz de la siguiente manera:
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"
Si necesita trabajar con tipos
Decimal
la suma total ya está cubierta por la propiedad de extensión de protocolo
Numeric
, por lo que solo necesita implementar la propiedad promedio:
extension Collection where Element == Decimal {
var average: Decimal {
return isEmpty ? 0 : total / Decimal(count)
}
}
Tienes algunos errores en tu código:
//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)
Un delineador pequeño, usando el antiguo Objective-C KVC traducido en Swift:
let average = (votes as NSArray).value(forKeyPath: "@avg.floatValue")
También puedes tener la suma:
let sum = (votes as NSArray).value(forKeyPath: "@sum.floatValue")
Más sobre esta gema olvidada: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/CollectionOperators.html