Javascript 将数字限制为段的最优雅方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11409895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:45:23  来源:igfitidea点击:

What's the most elegant way to cap a number to a segment?

javascriptcoding-style

提问by Samuel Rossille

Let's say x, aand bare numbers. I need to cap xto the bounds of the segment [a, b].

假设xab是数字。我需要限制x到段的边界[a, b]

I can write Math.max(a, Math.min(x, b)), but i don't think it's very easy to read. Does anybody has a clever way to write this in a more readable way?

我会写Math.max(a, Math.min(x, b)),但我觉得读起来不太容易。有没有人有一种聪明的方法以更易读的方式写这个?

回答by Otto Allmendinger

The way you do it is pretty standard. You can define a utility clampfunction:

你这样做的方式非常标准。您可以定义一个效用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);
};

(Although extending language built-ins is generally frowned upon)

(虽然扩展语言内置程序通常是不受欢迎的)

回答by dweeves

a less "Math" oriented approach ,but should also work , this way, the < / > test is exposed (maybe more understandable than minimaxing) but it really depends on what you mean by "readable"

一种不太面向“数学”的方法,但也应该有效,这样,</ > 测试是公开的(可能比最小化更容易理解),但这实际上取决于您所说的“可读”是什么意思

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

回答by Tomas Nikodym

Update for ECMAScript 2017:

ECMAScript 2017 更新:

Math.clamp(x, lower, upper)

But note that as of today, it's a Stage 1 proposal. Until it gets widely supported, you can use a polyfill.

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

回答by CAFxX

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

回答by Nobita

This does not want to be a "just-use-a-library" answer but just in case you're using Lodash you can use .clamp:

这不想成为“只是使用图书馆”的答案,但以防万一您使用的是 Lodash,您可以使用.clamp

_.clamp(yourInput, lowerBound, upperBound);

So that:

以便:

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

Here is its implementation, taken from Lodash source:

这是它的实现,取自 Lodash源代码

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

Also, it's worth noting that Lodash makes single methods available as standalone modules, so in case you need only this method, you can just install it without the rest of the library:

此外,值得注意的是,Lodash 将单个方法作为独立模块提供,因此如果您只需要这个方法,您可以直接安装它而不需要库的其余部分:

npm i --save lodash.clamp

回答by bingles

If you are able to use es6 arrow functions, you could also use a partial application approach:

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

回答by Ricardo

If you don't want to define any function, writing it like Math.min(Math.max(x, a), b)isn't that bad.

如果您不想定义任何函数,那么编写它Math.min(Math.max(x, a), b)也不错。

回答by stoke motor

In the spirit of arrow sexiness, you could create a micro clamp/constrain/gate/&c. function using rest parameters

本着箭头性感的精神,您可以创建一个微型夹具/约束/门/&c。使用rest参数的函数

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

Then just pass in three values

然后只需传入三个值

clamp(100,-3,someVar);

That is, again, if by sexy, you mean 'short'

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

回答by user947856

My favorite:

我最喜欢的:

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