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 矢木浩人