将数字限制为细分市场的最优雅方式是什么?

时间:2012-07-10 08:58:54

标签: javascript coding-style

我们说xab是数字。我需要将x限制在细分[a, b]的范围内。

我可以写Math.max(a, Math.min(x, b)),但我不认为这很容易阅读。有没有人有一种聪明的方式以更易读的方式写这个?

10 个答案:

答案 0 :(得分:160)

你这样做很标准。您可以定义一个实用程序clamp函数,如描述here

/**
 * 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);
};

(虽然扩展语言内置函数通常不受欢迎)

答案 1 :(得分:47)

一种较少“数学”导向的方法,但也应该有效,这样,< />测试暴露(可能比minimaxing更容易理解),但它实际上取决于你所说的“可读”

function clamp(num, min, max) {
  return num <= min ? min : num >= max ? max : num;
}

答案 2 :(得分:32)

ECMAScript 2017更新:

g2 = uint8(mat2gray(g1) * 255);

但请注意,截至今天,这是第1阶段proposal。在获得广泛支持之前,您可以使用polyfill

答案 3 :(得分:12)

Math.clip = function(number, min, max) {
  return Math.max(min, Math.min(number, max));
}

答案 4 :(得分:8)

这不是一个“只是使用图书馆”的答案,但是如果你使用的是Underscore / Lodash,你可以使用.clamp

_.clamp(yourInput, lowerBound, upperBound);

那样:

_.clamp(22, -10, 10); // => 10

以下是它的实现,取自Lodash source

/**
 * 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

答案 5 :(得分:4)

如果您能够使用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

答案 6 :(得分:3)

本着箭头性感的精神,你可以创造一个微观 夹紧/约束/栅/和C。功能使用休息参数

var clamp = (...v) => v.sort((a,b) => a-b)[1];

然后传递三个值

clamp(100,-3,someVar);

也就是说,如果是性感的话,你的意思是“短暂”

答案 7 :(得分:2)

这会将三元选项扩展为if / else,将其最小化等效于三元选项,但不会牺牲可读性。

const clamp = (value, min, max) => {
  if (value < min) return min;
  if (value > max) return max;
  return value;
}

缩小为35b(如果使用function,则缩小为43b):

const clamp=(c,a,l)=>c<a?a:c>l?l:c;

此外,根据您使用的性能工具或浏览器,您会发现基于数学的实现或基于三元的实现更快的各种结果。在性能大致相同的情况下,我会选择可读性。

答案 8 :(得分:0)

如果您不想定义任何功能,那么像next那样写它并不是那么糟糕。

答案 9 :(得分:-4)

我的最爱:

[min,x,max].sort()[1]