ディスクサイズフォーマット
一覧に 12345678 と出ていると、読む側は毎回桁を数えることになります。11.8 MB と書いてあれば一目です。数字を見て単位を選び、文字列にして返すのが今回の仕事です。
単位ごとに分岐を書くと、増えるたびに書き足す
1024 未満なら B、1048576 未満なら KB、と条件を並べていく書き方もできます。動きはしますが、単位が 5 つあれば分岐も 5 本になり、境目の数字を手で書くので 1 桁の打ち間違いに気づけません。単位を 1 つ足したくなるたびに、分岐も 1 本足すことになります。
何回割れるかを数える
考え方を変えます。割れるあいだ割り続けて、割った回数を数えます。0 回なら一番下の単位、1 回なら 1 つ上、2 回ならその上です。時間の単位で試すと動きが見えます。
Python
def stepsToShrink(seconds):
steps = 0
while seconds >= 60:
seconds /= 60
steps += 1
return steps
print(stepsToShrink(90)) # 1
print(stepsToShrink(7200)) # 2割り終わったあとの値も一緒に持っておけば、表示に使う数字がそのまま手に入ります。そして数えた回数は、添字としても使えます。単位を並び順のまま配列に入れておけば、分岐を 1 本も書かずに単位が選べます。
Python
UNITS = ["秒", "分", "時間"]
print(UNITS[stepsToShrink(7200)]) # 時間容量なら、割る数が 60 ではなく 1024 になり、配列の中身が 5 語に増えるだけです。単位を足したくなったら配列に 1 語足せば済みます。
一番上の単位で止める
割れるあいだ割り続けると、一番上の単位を超える大きさが来たときに配列の外へ出ます。Python なら添字が範囲外で落ち、JavaScript なら undefined が単位として表示されます。繰り返しの条件に「添字がまだ最後の単位に届いていない」を足して、上限で止めます。条件が 2 つ並ぶので、片方だけ書いて満足しないように気をつけます。
小数第 1 位に固定する
1.0 KB と 1 KB は、文字列としては別物です。テストは文字列そのものを比べるので、桁をそろえておく必要があります。Python は書式指定、JavaScript は toFixed で 1 桁に固定できます。
Python
print(f"{2.0:.1f}") # 2.0JavaScript
console.log((1.5).toFixed(1)); // "1.5"戻り値が文字列なので、間違えたときに何がどうずれたのかが目で見えます。単位が 1 つずれているのか、桁が足りないのか、区切りの空白が抜けているのか、テストの出力を読むだけで切り分けられます。
Java の
String.format("%.1f", v)は環境によって小数点が,になります。Locale.USを明示すると揺れません。
要件
- formatSize という名前の関数を実装すること
- B / KB / MB / GB / TB の 5 単位を扱うこと
- 小数第 1 位までの文字列を返すこと
入出力例
formatSize(0) → "0.0 B"
formatSize(500) → "500.0 B"
formatSize(1024) → "1.0 KB"
formatSize(1500) → "1.5 KB"
formatSize(1048576) → "1.0 MB"
formatSize(1073741824) → "1.0 GB"