Скажем, x
, a
и b
- числа. Мне нужно ограничить x
до границ сегмента [a, b]
.
Я могу написать Math.max(a, Math.min(x, b))
, но я не думаю, что это очень легко читать. У кого-нибудь есть умный способ написать это более читаемым способом?
Скажем, x
, a
и b
- числа. Мне нужно ограничить x
до границ сегмента [a, b]
.
Я могу написать Math.max(a, Math.min(x, b))
, но я не думаю, что это очень легко читать. У кого-нибудь есть умный способ написать это более читаемым способом?
То, как вы это делаете, довольно стандартно. Вы можете определить функцию утилиты 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);
};
(Хотя расширение языковых встроенных функций обычно не одобряется)
менее ориентированный на "математику" подход, но также должен работать таким образом, / " > (возможно, более понятным, чем минимакс), но это действительно зависит от того, что вы подразумеваете под" читаемым"
function clamp(num, min, max) {
return num <= min ? min : num >= max ? max : num;
}
Обновление для ECMAScript 2017:
Math.clamp(x, lower, upper)
Но обратите внимание, что на сегодняшний день это этап 1 proposal. Пока он не будет широко поддержан, вы можете использовать polyfill.
Math.clip = function(number, min, max) {
return Math.max(min, Math.min(number, max));
}
В духе сексуальности стрелки вы можете создать микро зажим/ограничить/ворота/& C. функция с использованием параметров отдыха
var clamp = (...v) => v.sort((a,b) => a-b)[1];
Затем просто передайте три значения
clamp(100,-3,someVar);
То есть, опять же, если по сексуальности вы имеете в виду "короткие"
Это не означает, что вы хотите использовать ответ "just-use-a-library", но если вы используете 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
Если вы можете использовать функции стрелок 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
Вы также можете использовать этот повторно используемый номер-зажимный компонент, который возвращает число, значение которого ограничено заданным диапазоном.
Пример:
clamp(50, 5, 10) // => 5
Как это работает:
function clamp(value, min, max) {
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}
Мой любимый:
[min,x,max].sort()[1]