回答:
それを行う方法はかなり標準的です。ユーティリティclamp
関数を定義できます:
/**
* Returns a number whose value is limited to the given range.
*
* Example: limit the output of this computation to between 0 and 255
* (x * 255).clamp(0, 255)
*
* @param {Number} min The lower boundary of the output range
* @param {Number} max The upper boundary of the output range
* @returns A number in the range [min, max]
* @type Number
*/
Number.prototype.clamp = function(min, max) {
return Math.min(Math.max(this, min), max);
};
(ただし、組み込み言語の拡張は一般的に推奨されません)
Math.min
とはMath.max
長いのパラメータと同様に無関係でMath.min
あるmax
とのパラメータMath.max
ですmin
。
Number.prototype
この場合)の拡張は、さまざまな理由で不適切です。developer.mozilla.org/en-US/docs/Web/JavaScript/…にある
あまり「数学」指向のアプローチではありませんが、この方法でも機能するはずです。この方法では、</>テストが公開されます(ミニマックスよりも理解しやすいかもしれません)が、実際には「読み取り可能」の意味に依存します
function clamp(num, min, max) {
return num <= min ? min : num >= max ? max : num;
}
Math.random()
呼び出しからオーバーヘッドを取り除くと、この単純なアプローチは10倍速くなります。
Math.clip = function(number, min, max) {
return Math.max(min, Math.min(number, max));
}
prototype
実際に関数を使用する場合は非常にエレガントなものを拡張することを検討します。
これは「ライブラリの使用のみ」の回答にはなりたくありませんが、Lodashを使用している場合に備えて、次のように使用できます.clamp
。
_.clamp(yourInput, lowerBound, upperBound);
そのため:
_.clamp(22, -10, 10); // => 10
/**
* The base implementation of `_.clamp` which doesn't coerce arguments.
*
* @private
* @param {number} number The number to clamp.
* @param {number} [lower] The lower bound.
* @param {number} upper The upper bound.
* @returns {number} Returns the clamped number.
*/
function baseClamp(number, lower, upper) {
if (number === number) {
if (upper !== undefined) {
number = number <= upper ? number : upper;
}
if (lower !== undefined) {
number = number >= lower ? number : lower;
}
}
return number;
}
また、Lodashは単一のメソッドをスタンドアロンモジュールとして使用できるようにするため、このメソッドのみが必要な場合は、ライブラリの残りの部分なしでインストールできます。
npm i --save lodash.clamp
es6矢印関数を使用できる場合は、部分的なアプリケーションアプローチを使用することもできます。
const clamp = (min, max) => (value) =>
value < min ? min : value > max ? max : value;
clamp(2, 9)(8); // 8
clamp(2, 9)(1); // 2
clamp(2, 9)(10); // 9
or
const clamp2to9 = clamp(2, 9);
clamp2to9(8); // 8
clamp2to9(1); // 2
clamp2to9(10); // 9
矢印のセクシーさの精神で、マイクロクランプ/拘束/ゲート/&cを作成できます。レストパラメータを使用する関数
var clamp = (...v) => v.sort((a,b) => a-b)[1];
次に、3つの値を渡します
clamp(100,-3,someVar);
つまり、セクシーな場合は、「短い」という意味です
clamp
複雑なロジックがある場合(たとえ「セクシー」であっても)、配列とソートを使用しないでください
これにより、3項オプションが、最小化されたif / elseに展開され、3項オプションと同等になりますが、読みやすさは犠牲になりません。
const clamp = (value, min, max) => {
if (value < min) return min;
if (value > max) return max;
return value;
}
35b(またはを使用している場合は43b function
)に縮小します。
const clamp=(c,a,l)=>c<a?a:c>l?l:c;
また、使用するパフォーマンスツールまたはブラウザーに応じて、数学ベースの実装と3値ベースの実装のどちらが高速であるかについて、さまざまな結果が得られます。ほぼ同じパフォーマンスの場合、読みやすさを選びます。
お気に入り:
[min,x,max].sort()[1]
[1,5,19].sort()[1]
これは19を返します。次のように修正できます。[min,x,max].sort(function(a, b) { return a - b; })[1]
しかし、これはもうセクシーではありません。頻繁に使用する場合を除いて、3つの数値を比較するためだけに新しい配列を作成すると、パフォーマンスの問題になる可能性があります。
[min, x, max].sort((a,b) => a-b)[1]