Swift - 取字典中元素的平均值

时间:2016-09-23 03:58:05

标签: swift dictionary

我已经查看了StackOverflow,但是没有找到任何谈论在字典中获取特定Int或Double的平均值的地方。这是我创建的自定义词典:

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

有人知道语法吗?谢谢你帮助一个菜鸟!

3 个答案:

答案 0 :(得分:1)

最漂亮的方法是使用 reduce 功能。你给它一个起始值,以及一个解释如何在字典中添加下一个项目的闭包。在这种情况下,我们的起始值将是四个元素的元组。 $ 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)

编辑:快速更改代码,忘记指定从字典中添加值。

还有一个编辑:上面假设它们也是你在每个字典值中创建的结构或类中的变量名。

答案 1 :(得分: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)")
}

答案 2 :(得分: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
    ...
}