174 votes

Quelle est la façon la plus élégante de limiter un nombre à un segment ?

Disons que x a b sont des nombres. Je dois limiter x aux limites du segment [a, b].

En d'autres termes, j'ai besoin d'une fonction clamp :

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

Quelqu'un peut-il en trouver une version plus lisible ?

238voto

Otto Allmendinger Points 11853

La façon dont vous le faites est assez standard. Vous pouvez définir une fonction utilitaire 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);
};

(Bien que l'extension du langage intégré soit généralement mal vue)

86voto

dweeves Points 3326

une approche moins « mathématique », mais qui devrait également fonctionner, de cette façon, le test </> est exposé (peut-être plus compréhensible que la minimaxation), 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
}

68voto

Tomas Nikodym Points 2734

Il y a une proposition pour ajouter un ajout à l'objet Math intégré pour le faire :

Math.clamp(x, lower, upper)

Mais notez qu'à partir d'aujourd' hui, il s'agit d'une proposition d'étape 1. Jusqu'à ce qu'il soit largement pris en charge (ce qui n'est pas garanti), vous pouvez utiliser un polyfill.

34voto

CAFxX Points 3911

Un moyen simple serait d'utiliser

Math.max(min, Math.min(number, max));

et vous pouvez évidemment définir une fonction qui englobe ceci :

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

À l'origine, cette réponse a également ajouté la fonction ci-dessus à l'objet global Math, mais c'est une relique d'une époque révolue, elle a donc été supprimée (merci @Aurelio pour la suggestion)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X