Disons que x
, a
et b
sont des nombres. J'ai besoin de plafonner x
aux limites du segment [a, b]
.
Je peux écrire Math.max(a, Math.min(x, b))
, mais je ne pense pas que ce soit très facile à lire. Est-ce que quelqu'un a un moyen intelligent d'écrire cela de manière plus lisible?
La façon dont vous le faites est assez standard. Vous pouvez définir une fonction utilitaire clamp
comme décrit ici :
/**
* 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);
};
(Bien que l'extension de la langue intégrée soit généralement mal vue)
une approche moins "mathématique", mais devrait également fonctionner de cette façon, le test </> est exposé (peut-être plus compréhensible que minimiser) mais cela dépend vraiment de ce que vous entendez par "lisible"
function clamp(num, min, max) {
return num <= min ? min : num >= max ? max : num;
}
Mise à jour pour ECMAScript 2017:
Math.clamp(x, lower, upper)
Mais notez qu’à ce jour, c’est une étape 1 proposition . En attendant que cela soit largement supporté, vous pouvez utiliser un polyfill .
Math.clip = function(number, min, max) {
return Math.max(min, Math.min(number, max));
}
Cela ne veut pas être une réponse "juste-utiliser-une-bibliothèque" mais juste au cas où vous utilisez Underscore/Lodash, vous pouvez utiliser .clamp
:
_.clamp(yourInput, lowerBound, upperBound);
Pour que:
_.clamp(22, -10, 10); // => 10
Voici son implémentation, tirée de 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;
}
Il convient également de noter que Lodash propose des méthodes uniques disponibles en tant que modules autonomes. Par conséquent, si vous n’avez besoin que de cette méthode, vous pouvez simplement l’installer sans le reste de la bibliothèque:
npm i --save lodash.clamp
Si vous pouvez utiliser les fonctions fléchées es6, vous pouvez également utiliser une approche d'application partielle:
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
Dans l’esprit de la sensualité des flèches, vous pouvez créer un micro Clamp/contraindre/gate/& c. fonction utilisant des paramètres de repos
var clamp = (...v) => v.sort((a,b) => a-b)[1];
Il suffit ensuite de transmettre trois valeurs
clamp(100,-3,someVar);
C'est-à-dire, encore une fois, si par sexy, vous voulez dire «court»
Si vous ne voulez définir aucune fonction, l'écrire comme suit: Math.min(Math.max(x, a), b)
n'est pas si mal que ça.