Заставить мою функцию вычислять среднее значение массива Swift

Я хочу, чтобы моя функция вычисляла среднее значение моего массива типа 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]

Как я могу назвать среднее здесь, чтобы получить среднее?

7 ответов

Решение

Вы должны использовать метод redu () для суммирования массива следующим образом:

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(Int(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)
    }
}

У вас есть ошибки в вашем коде:

//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)

Небольшой лайнер, использующий старомодный 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

У меня есть набор сигналов, которые создаются в функции обновления, для получения скользящего среднего я использую эту функцию, которая вычисляет среднее значение в окне, определяемом периодом скользящего среднего. Поскольку моя цель - собрать новый набор сигналов, содержащий среднее значение, я отброшу сигналы из исходного набора. Это хорошее решение для тех, кто хочет иметь скользящую среднюю в функции обновления, например, в 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
}

Простое среднее с фильтром при необходимости (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, +)
}

Предоставлено: MathKit Адриана Хоударта, в основном без изменений.


Симпатичное обновление:

Я нашел следующее в языке программирования Swift:

В приведенном ниже примере вычисляется среднее арифметическое (также известное как среднее) для списка чисел любой длины:

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

Добавление этих расширений в Array позволит вычислить среднее значение значений Int и FloatingPoint:

      extension Array where Element: BinaryInteger {

  var average: Element? {
      guard let elementCount = Element(exactly: count) else { return nil }
      return reduce(0) { $0 + $1 } / elementCount
  }
}

extension Array where Element: FloatingPoint {

var average: Element? {
      guard let elementCount = Element(exactly: count) else { return nil }
      return reduce(0) { $0 + $1 } / elementCount
  }
}
Другие вопросы по тегам