ループで集計
累積の型
合計を出すコードは、どの言語でもほぼ同じ形になります。
Go
total := 0
for i := 0; i < len(prices); i++ {
total += prices[i]
}外で入れ物を用意して、中で足していくという形です。入れ物をループの中で作ると毎回リセットされてしまうので、必ず外に置きます。
Go ではゼロ値があるので、var total int と書くだけでも 0 から始められます。
平均を出すときの落とし穴
合計を件数で割れば平均です。ただし int どうしの割り算は小数が消えます。
Go
total := 1200 + 999 + 800 // 2999
average := total / 3 // 999。999.67 ではない小数まで欲しいなら、第2章でやったとおり float64 に変換します。
Go
average := float64(total) / float64(len(prices)) // 999.6666...どちらが正しいかは場面によります。 平均価格を「円」で表示するなら int のままで十分ですし、統計として扱うなら小数が要ります。Go が勝手に決めないぶん、書く側が選ぶことになります。
0件のときに落ちる
合計を件数で割るコードには、必ずこの穴があります。
Go
average := total / len(prices) // 0件のとき panicプレーンテキスト
panic: runtime error: integer divide by zero0で割ると実行時に止まります。 商品が1件も無い状態は普通に起こるので、先に弾きます。
Go
if len(prices) == 0 {
return 0
}テストで 0 件を試さないと気づけない類のバグです。このコースの演習には、意図して0件のテストを入れてあります。
件数を数える
条件に合うものだけ数えるのも、同じ形です。
Go
count := 0
for i := 0; i < len(prices); i++ {
if prices[i] >= 1000 {
count++
}
}合計・件数・最大・最小は、どれも「外に入れ物、中で更新」の形で書けます。最大値だけは、入れ物の初期値を 0 にするとすべて負の数のときに間違えます。1件目の値で始めるのが安全です。
要件
N件 合計M円 平均K円の形を返す- 平均は合計を件数で割る(int の割り算なので小数は切り捨て)
- 0件のときは
0件だけを返す。割り算をしない
入出力例
summarize([1200,999,800]) → "3件 合計2999円 平均999円"
summarize([1200]) → "1件 合計1200円 平均1200円"
summarize([1000,2000]) → "2件 合計3000円 平均1500円"
summarize([0,100]) → "2件 合計100円 平均50円"ヒント
編集 ゆめさく編集部