Swift コントロールブレーク Map Reduce
Swift コントロールブレーク 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 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) }
© 2006 矢木浩人