2016-09-23 8 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

もっとも良い方法は、の機能を減らすを使用することです。開始値を指定し、次の項目を辞書に追加する方法を説明するクロージャーを指定します。この場合、開始値は4つの要素のタプルになります。 $ 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つ編集:上記は、それらが各辞書値で作成する構造体またはクラスの変数名であることを前提としています。

0

DayDataのオブジェクトを渡してその関数を持つ関数を作成することは、それがかなり困難になることを認識します。

私がお勧めするのは、各パラメータに対して4つの別々の関数を作成するか、数値システムを作成することです。私はあなたが両方を達成する方法を示します。

このメソッドは、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 
    ... 
} 
関連する問題