| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

Swift コントロールブレーク Map Reduce

提供: MyMemoWiki
2022年6月19日 (日) 02:20時点におけるPiroto (トーク | 投稿記録)による版 (→‎Swift コントロールブレーク Map Reduce)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

Swift コントロールブレーク Map Reduce

Java

コントロールブレーク

   func setData() {
        let start = Calendar.current.date(byAdding:.day, value: -15, to: Date())
        let end = Date()
        let predicate = HKQuery.predicateForSamples(withStart: start, end: end)
        let sampleType = HKQuantityType.quantityType(forIdentifier: .bodyMass)!
        
        let query = HKSampleQuery(
            sampleType: sampleType,
            predicate: predicate,
            limit: HKObjectQueryNoLimit,
            sortDescriptors: nil) {
            (query, results, error) in
            
                var samples = (results as! [HKQuantitySample]).makeIterator()
                
                var data:Dictionary<String, (high:Double, low:Double, open:Double, close:Double)> = [:]
                
                let formatter = DateFormatter()
                formatter.dateFormat = "yy/M/d"
                
                var item = samples.next()
                if item != nil  {
                    var key1:String? = formatter.string(from: item!.startDate)
                    while item != nil {
                        // 日付単位
                        var isFind = false
                        var isFirst = true
                        var open:Double?
                        var close:Double?
                        var bm:Double?
                        var high:Double?
                        var low:Double?
                        while item != nil && key1 == formatter.string(from: item!.startDate) {
                            isFind = true
                            bm = item!.quantity.doubleValue(for: .gram()) / 1000
                            
                            if isFirst {
                                open = bm
                                high = bm
                                low = bm
                                isFirst = false
                            }
                            if bm! > high! {
                                high = bm
                            }
                            if bm! < low! {
                                low = bm
                            }
                            print("\(key1!) BM:\(bm!) OPEN:\(open!) HIGH:\(high!) LOW:\(low!) ")
                            item = samples.next()
                        }
                        close = bm
                        
                        if isFind {
                            // 要素を辞書に格納
                            data[key1!] = (high:high!, low:low!, open:open!, close:close!)
                        }
                        if item != nil {
                            key1 = formatter.string(from: item!.startDate)
                        }
                        print("BREAK")
                    }
                }
                
                var yValues: [CandleChartDataEntry] = []
                var xValues: [String] = []
                var x = 0
                var current = start!
                
                while current <= end {
                    let key = formatter.string(from: current)
                    
                    var de: CandleChartDataEntry?
                    if let ds = data[key] {
                        de = CandleChartDataEntry(x: Double(x), shadowH: ds.high, shadowL: ds.low, open: ds.open, close: ds.close)
                    } else {
                        de = CandleChartDataEntry(x: Double(x), shadowH: 0.0, shadowL: 0.0, open: 0.0, close: 0.0)
                    }
                    
                    yValues.append(de!)
                    xValues.append(key)
                    
                    current = Calendar.current.date(byAdding: .day, value:1, to: current)!
                    x += 1
                    
                    print("KEY:\(key) CURRENT:\(String(describing:current)) START:\(String(describing:start)) END:\(String(describing:end)) DE:\(String(describing:de))")
                    print("COMPARE:\(current <= end)")
                }
                
            DispatchQueue.main.async {
                self.chart.xAxis.valueFormatter = IndexAxisValueFormatter(values: xValues)
                let set = CandleChartDataSet(entries: yValues, label: "bodymass")
                set.valueFont = UIFont(name: "HelveticaNeue-Light", size: 10)!
                set.drawValuesEnabled = true
                
                let data = CandleChartData(dataSet: set)
                self.chart.data = data
            }
        }
        self.healthStore?.execute(query)
    }

Map Reduceで書き直し

    func setData() {
        let start = Calendar.current.date(byAdding:.day, value: -15, to: Date())
        let end = Date()
        let predicate = HKQuery.predicateForSamples(withStart: start, end: end)
        let sampleType = HKQuantityType.quantityType(forIdentifier: .bodyMass)!
        
        let query = HKSampleQuery(
            sampleType: sampleType,
            predicate: predicate,
            limit: HKObjectQueryNoLimit,
            sortDescriptors: nil) {
            (query, results, error) in

                let formatter = DateFormatter()
                formatter.dateFormat = "yy/M/d"

                let samples = (results as! [HKQuantitySample])
                
                var dtGrp:Dictionary<String, [Double]> = [:]
                
                // 日付グループ化
                print("--- グループ化 Date:BM ---")
                let _ = samples.map { sample in
                    let key = formatter.string(from: sample.startDate)
                    let bm = sample.quantity.doubleValue(for: .gram()) / 1000
                    
                    var list = dtGrp[key]
                    if list == nil {
                        list = []
                    }
                    list!.append(bm)
                    dtGrp[key] = list
                    print("key:\(key) value:\(bm)")
                }
                
                // 集計
                print("--- 集計 ---")
                var dtEnt:Dictionary<String, (high:Double, low:Double, open:Double, close:Double)> = [:]
                dtGrp.keys.forEach { key in
                    
                    let list = dtGrp[key]!
                    
                    let open = list.first!
                    let close = list.last!
                    let high = list.reduce(open) { (bm1, bm2) -> Double in
                        return bm1 > bm2 ? bm1 : bm2
                    }
                    let low = list.reduce(open) { (bm1, bm2) -> Double in
                        return bm1 < bm2 ? bm1 : bm2
                    }
                    dtEnt[key] = (high:high, low:low, open:open, close:close)
                    print("key:\(key) open:\(open) close:\(close) high:\(high) low:\(low)")
                }

                var yValues: [CandleChartDataEntry] = []
                var xValues: [String] = []
                var x = 0
                var current = start!

                while current <= end {
                    let key = formatter.string(from: current)

                    var de: CandleChartDataEntry?
                    if let ds = dtEnt[key] {
                        de = CandleChartDataEntry(x: Double(x), shadowH: ds.high, shadowL: ds.low, open: ds.open, close: ds.close)
                    } else {
                        de = CandleChartDataEntry(x: Double(x), shadowH: 0.0, shadowL: 0.0, open: 0.0, close: 0.0)
                    }

                    yValues.append(de!)
                    xValues.append(key)

                    current = Calendar.current.date(byAdding: .day, value:1, to: current)!
                    x += 1

                    print("KEY:\(key) CURRENT:\(String(describing:current)) START:\(String(describing:start)) END:\(String(describing:end)) DE:\(String(describing:de))")
                    print("COMPARE:\(current <= end)")
                }
                
            DispatchQueue.main.async {
                self.chart.xAxis.valueFormatter = IndexAxisValueFormatter(values: xValues)
                let set = CandleChartDataSet(entries: yValues, label: "bodymass")
                set.valueFont = UIFont(name: "HelveticaNeue-Light", size: 10)!
                set.drawValuesEnabled = true

                let data = CandleChartData(dataSet: set)
                self.chart.data = data
            }
        }
        self.healthStore?.execute(query)
    }