JavaScript

Math.maxとMath.minで書く値の上限下限設定(まだif文使ってるの?)


背景

皆さんはこれまで数値の上限設定する場合にどのように書いていましたか?ひよっこエンジニアの私はif文を使ってしていました。

例えば、1から5の間に制限したい場合....

const maxNum = 5; 

const minNum = 1;
let num = 3; // 初期値を3としておく

// ------------
// 加算された場合
// ------------
num += 3; // この時点でnumは6
if (num >= maxNum){ //しかし5以上になっているので
num = maxNum // numは5に書き換えられる
}
console.log(num) // 結果:5(最大制限値に収まる)
// ------------
// 減産された場合
// ------------
num -= 3 //この時点ではnumは0
if (num <= minNum){ //numは0で1以下でこれに当てはまるので
num = minNum //numは1にする
}
console.log(num) // 結果:1(最大制限値に収まる)

最近までこの書き方をしていたのですが、メンターの方にかっこいい書き方を教わったので、紹介します!


書き方

それがこちら!

const maxNum = 5; 

const minNum = 1;
let num = 3;

// 1. 加算の場合
Math.max(minNum, Math.min(maxNum, num + 3));
// 結果: 5

// 2. 減算の場合
Math.max(minNum, Math.min(maxNum, num - 10));
// 結果: 1

すごくないですか?!Math.max()Math.min()を組み合わせるだけで設定できちゃうんですよ!(え、知らなかったの僕だけ?ww)

ここで何が起きているか説明します。一つ目の式をサンプルとして見ていきます。

Screen_Shot_2018-10-30_at_16_04_14.png


説明

まず、① Max.min()の中身を見てみましょう。

Math.min(maxNum, num + 3)

// ↓ つまり
Math.min(5, 3 + 3))

そうですよね。maxNumには5が入っていて、numには3が入っています。この場合、Math.min()で、56(3+3)を比較し、小さい方である5を取得しています。

次に②Max.max()を見てみます。

Math.max(minNum, Math.min(maxNum, num + 3));

// ↓ つまり
Math.max(1, Math.min(5, 3 + 3));
// ↓ つまり
Math.max(1, 5);

minNumには1が入っております。そして後ろのMath.min(maxNum, num + 3)は先ほど見たように、結果として5が入ってきます。

ということはMath.max(1, 5)では、15を比較して、大きい方である5を取得します。

よって、結果として、こちらの式は5が結果として出てくるということになります。

計算式が減算の場合も同じようになります。

// 2. 最小値の制限 

Math.max(minNum, Math.min(maxNum, num - 10));
// 結果: 1

Screenshot_2018_10_30_16_38.png

まず、Math.min()の中身で、5-7(3-10)を比較し、より小さい方の-7を取得します。次に外側のMath.max()1-7を比較し、大きい方を取るので、1が出力されることになりますね。


他の出力例

const maxNum = 10;  //最大値

const minNum = 5; //最小値
let num = 6;

let val = 2 //加算値が2の場合
Math.max(minNum, Math.min(maxNum, num + val));
// 結果: 8
// Math.minで10と8を比べ、小さい方の8が取れる。
// そしてMath.maxで5と8が比較され大きい方の8が取れる。

let val = 8 //加算値が8の場合
Math.max(minNum, Math.min(maxNum, num + val));
// 結果: 10

let val = -4 //加算値が-4の場合
Math.max(minNum, Math.min(maxNum, num + val));
// 結果: 5

let val = 2 //乗算値が2の場合
Math.max(minNum, Math.min(maxNum, num * val));
// 結果: 10

let val = 4 //減算値が4の場合
Math.max(minNum, Math.min(maxNum, num - val));
// 結果: 5

計算式で、足し算、引き算、掛け算、割り算など何をしても同じですので、演算子を書き換えるだけでOKです。


最後に

Math.max()ならびにMath.min()の中の最大値そして最小値に直接数字を書いてもいいですが、マジックナンバーとなってしまい、他の人がコードを見たときに分かりづらくなりますので、constで先に定義しております。

ちなみにMath.max()Math.min()を入れ替えても大丈夫です。(外側にMath.min()内側にMath.max())その場合はきちんと第二引数を間違えないように注意しましょう。

書きながら思いましたが、中々説明って難しいですね。。

言葉足らずな部分が多いですが、コメントで補足等頂けますと嬉しいです。