2016-09-23 42 views
0

我查看了StackOverflow,但沒有找到任何說明在字典中採用特定Int或Double的平均值的地方。這是我創建的自定義字典:Swift - 以字典的元素的平均值

var allInformationByDate = [ 
"1989-06-20": DayData(sales: 0, doorsKnocked: 0, milesWalked: 0.00, hoursWorked: 0.00), 
"2016-06-22": DayData(sales: 2, doorsKnocked: 30, milesWalked: 2.00, hoursWorked: 3.00), 
"2016-08-16": DayData(sales: 4, doorsKnocked: 30, milesWalked: 10.00, hoursWorked: 0.00) 
] 

所以我會尋找獲得這些每個的平均值。例如:

var avgSales = average(sales) = 2 
var avgDoors = average(doorsKnocked) = 20 
var avgMiles = average(milesWalked) = 4.0 
var avgHours = average(hoursWorked) = 1.0 

有人知道語法嗎?感謝您幫助noob!

回答

1
var allInformationByDate = [ 
    "1989-06-20": DayData(sales: 0, doorsKnocked: 0, milesWalked: 0.00, hoursWorked: 0.00), 
    "2016-06-22": DayData(sales: 2, doorsKnocked: 30, milesWalked: 2.00, hoursWorked: 3.00), 
    "2016-08-16": DayData(sales: 4, doorsKnocked: 30, milesWalked: 10.00, hoursWorked: 0.00) 
] 


override func viewDidLoad() { 
    super.viewDidLoad() 

    var avgSales:Double! = 0.0 
    var avgDoorsKnocked:Double! = 0.0 
    var avgMilesWalked:Double! = 0.0 
    var avgHoursWorked:Double! = 0.0 

    let totalDays = Double(allInformationByDate.count) 

    for (date, dayData) in allInformationByDate { 
     print("date: \(date)") 

     avgSales  = avgSales + Double(dayData.sales) 
     avgDoorsKnocked = avgDoorsKnocked + Double(dayData.doorsKnocked) 
     avgMilesWalked = avgMilesWalked + dayData.milesWalked 
     avgHoursWorked = avgHoursWorked + dayData.hoursWorked 

    } 

    avgSales  = avgSales/totalDays 
    avgDoorsKnocked = avgDoorsKnocked/totalDays 
    avgMilesWalked = avgMilesWalked/totalDays 
    avgHoursWorked = avgHoursWorked/totalDays 

    print("\(avgSales),\(avgDoorsKnocked),\(avgMilesWalked), \(avgHoursWorked)") 
} 
1

最漂亮的方法是使用減少函數。您給它一個起始值,並給出一個解釋如何在字典中添加下一個項目的閉包。在這種情況下,我們的初始值將是一個由四個元素組成的元組。 $ 0是指要添加的項目,$ 1是指在此迭代中添加的項目。您也可以將它們稱爲$ 0.0 & 0.1美元,但我認爲以前的方式看起來更好。

因此,在下面的關閉中,$ 0.0,$ 0.1,$ 0.2,$ 0.3是元組中的項目,起始爲(0.0,0.0,0.0,0.0),即初始元組。

(也注意到,您的整型變量將得到切斷,沒有給你正確的平均我要考慮的是他們都切換到雙打。)

let sums = allInformationByDate.reduce((0.0,0.0,0.0,0.0)) { 
    ($0.0 + Double($1.value.sales), $0.1 + Double($1.value.doorsKnocked), 
    $0.2 + $1.value.milesWalked, $0.3 + $1.value.hoursWorked) 
} 
let n = allInformationByDate.count 
let averages = (sums.0/n, sums.1/n, sums.2/n, sums.3/n) // divide each one by n. you could even give the items in the tuple names here) 

編輯:快速變化的代碼,忘記指定你正在從字典中的值添加。

多一個編輯:上面假設這些也是您在每個字典值中創建的結構或類中的變量名稱。

0

創建一個函數,您將DayData的對象傳入並具有該函數將會識別出相當困難。

我會建議要麼爲每個參數創建四個單獨的函數,要麼有一個數字系統。我會告訴你如何完成這兩個。

該方法假定DayData的成員可以公開訪問。

對於僅僅有每個參數的功能,它可能是這個樣子:

func averageSales(dictionary: [String: DayData]) -> Double { 
    var total = 0 
    for (date, dayData) in dictionary { 
     total += dayData.sales 
    } 
    return = total/dictionary.count 
} 

或者你可以擁有它採用了數字系統(1銷售,2撞倒門等類似的方法)。這不是一個非常優雅的解決方案,但是如果你喜歡,你可以使用它。

func average(dictionary: [String: DayData], parameterNumber: Int) -> Double { 
    var total = 0 
    if parameterNumber == 1 { //sales 
     for (date, dayData) in dictionary { 
      total += dayData.sales 
     } 
     return = total/dictionary.count 
    } else if parameterNumber == 2 { //knockedDoors 
    ... 
}