おそるおそる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ポイント”となっている部分が処理結果の表示となっています。
次回は
最終形である、プリンタ機能部分を追加します。うまくできるでしょうか!?
