172

としましょうxabは数字です。xセグメントの境界に制限する必要があります[a, b]

言い換えれば、私はクランプ関数が必要です:

clamp(x) = max( a, min(x, b) )

誰かがこれのより読みやすいバージョンを思い付くことができますか?

4

10 に答える 10

239

あなたがそれをする方法はかなり標準的です。ユーティリティ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);
};

(言語の組み込みを拡張することは一般的に眉をひそめますが)

于 2012-07-10T09:02:07.130 に答える
85

あまり「数学」指向のアプローチではありませんが、このように機能するはずです。このように、</>テストは公開されます(ミニマックスよりも理解しやすいかもしれません)が、実際には「読み取り可能」の意味によって異なります。

function clamp(num, min, max) {
  return num <= min 
    ? min 
    : num >= max 
      ? max 
      : num
}
于 2012-07-10T09:10:27.293 に答える
68

Mathこれを行うために、組み込みオブジェクトに追加を追加する提案があります。

Math.clamp(x, lower, upper)

ただし、現時点では、これはステージ 1 の提案であることに注意してください。広くサポートされるまで (保証されていません)、polyfillを使用できます。

于 2016-09-13T19:50:41.627 に答える
9

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
于 2017-11-02T20:46:15.817 に答える
7

関数を定義したくない場合は、次のように書くことMath.min(Math.max(x, a), b)はそれほど悪くありません。

于 2018-02-15T17:44:32.357 に答える
-7

お気に入り:

[min,x,max].sort()[1]
于 2016-03-04T19:15:06.447 に答える