おそるおそるSwift 2-4 デンタッキー(電卓)を作る ~電卓らしく計算させる機能を追加する~

Swift5+Xcode11.6
シリーズ2の4回目です。
今回のゴール
続きです。下の動画のように、一端の電卓として機能するように、計算させる機能を追加します。コードはContentView.swiftに書きました。
後半は変更がないので省略しています。
import SwiftUI struct ContentView: View { @State var inputArray :[String] = [] //リスト表示用 @State var inputStr :String = "" let CalStr :[String] = ["+","-"] //計算記号一覧 func outputStr(tmpStr :String) { // var str1 :String = "" if tmpStr == "C" { self.inputStr = "" self.inputArray = [] } else if tmpStr == "=" { var tmpStr2 :String = "" //配列の文字をキャッシュ var tmpResult :Double = 0.0 //計算途中の数値をキャッシュ var symbol :String //四則計算の区別 self.inputArray.append(self.inputStr) self.inputStr = tmpStr for item in self.inputArray { let str = item let start1 = str.startIndex //配列要素の最初の文字を取得 symbol = String(str[start1]) //それが計算記号に該当しない場合とする場合で処理振り分け if self.CalStr.contains(symbol) == false { tmpResult = atof(item) //atofは文字列をDoubleに変換する関数 } else { tmpStr2 = String(str.suffix(item.count - 1)) switch symbol { case "+": tmpResult += atof(tmpStr2) case "-": tmpResult -= atof(tmpStr2) default: tmpResult = 9999999.0 } } print("Aポイント: item:\(item) tmpStr2:\(tmpStr2) tmpResult:\(tmpResult)") } self.inputStr = String(tmpResult) } else if (self.CalStr.contains(tmpStr))&&(inputStr != "") { self.inputArray.append(self.inputStr) self.inputStr = tmpStr print("Bポイント:配列に追加しました。") for item in inputArray { print("現在の配列の状況は、\(item)") } } else { self.inputStr += tmpStr print("Cポイント:文字を追加しました。追加した文字は、\(self.inputStr)") } } var body: some View { VStack { Text("\(self.inputStr)") .font(.largeTitle) .fontWeight(.heavy) .foregroundColor(Color.red) .multilineTextAlignment(.trailing) .frame(width: 300.0)
「計算させるだけ」なのですが、処理がいきなり複雑になっています。まず、条件分岐を効率的にするために四則計算記号を値とする配列CalStrを作りました。とりあえず、加減記号しか入れていませんが、この配列に他の記号を追加して、後で説明する分岐部分で計算式を入力すれば、いかなる計算もできるようになります。
デバッグ画面を見ると、どのように動作しているか把握しやすいと思います。
”=”が押されると、配列の各要素をループさせて、次の処理を行います。
(1) 配列の最初の文字を確認し、計算記号であれば、その計算記号を変数symbolに入れます。計算記号でない場合は、そのまま配列の値を計算途中結果を格納する変数tmpResultに入れます。これは、基本的に最初の値に対応するための処理です。if文のcontainsという条件式は覚えないといけませんね。また、atofは文字列をダブル型に変更する関数です。文字列は計算できませんから必要です。
(2) 計算記号の場合は、symbolから値を読み、その内容に応じて処理を分岐させています。
(3) ループが終わったときのtmpResultが総計になりますので、それをinputStrに代入して、画面に表示させます。
上の動画では最後になってしまっていますが、”Cポイント”となっている部分が、以上の処理結果の表示になります。
他に、計算記号が入力されたときは”Bポイント”となっている部分が処理結果、数字が入力されたときは”Cポイント”となっている部分が処理結果の表示となっています。
次回は
最終形である、プリンタ機能部分を追加します。うまくできるでしょうか!?