Thomas Zilliox
Intégrateur CSS Freelance à Lyon

Modulo avec minimum et maximum en JavaScript

Parfois on cherche à faire un modulo entre deux valeurs personnalisées. C’est mon cas pour décoder des messages encodés avec un chiffre Vigenere, car nos permutations de lettres ont pour valeur minimum « A », soit « 1 », et non « 0 ».

25 % 26; // ✔ 25
26 % 26; // ⨯ 0 instead of 26
27 % 26; // ✔ 1
0 % 26; // ⨯ 0 instead of 26

Le premier problème des modulos en JavaScript est la possibilité d’obtenir des résultats négatifs, ce sujet a été résolu dans un article précédent et nous utiliserons le solution ici.

/**
 * Returns a value between a minimum and a maximum, using modulo to handle the overflows
 *
 * @param {number} number
 * @param {number} min - the minimum value
 * @param {number} max - the maximum value
 * @return {number} clamped value
 */
function moduloClamp(number, min, max) {
  return positiveModulo(number - min, max + 1 - min) + min;
}
Voir les dépendances
// See https://tzi.fr/js/modulos-positifs
function positiveModulo(number, divisor) {
  return ((number % divisor) + divisor) % divisor;
}

L’astuce ici est d’enlever la valeur minimum avant de réaliser son modulo puis de la rajouter au résultat obtenu. Il y a aussi une petite finesse sur la calcul du diviseur qui doit être max + 1 - min.

Exemples

moduloClamp(25, 1, 26); // ✔ 25
moduloClamp(26, 1, 26); // ✔ 26
moduloClamp(27, 1, 26); // ✔ 1
moduloClamp(0, 1, 26); // ✔ 26
moduloClamp(29, 30, 35); // ✔ 35
moduloClamp(36, 30, 35); // ✔ 30

Essayez


console.log(0 % 26);
console.log(positiveModulo(0, 26));
console.log(moduloClamp(0, 1, 26));

Amusez-vous bien, Thomas.

That's my face!

Thomas ZILLIOX

L'homme qui murmurait à l'oreille des chevrons.

Je développe, j'intègre, je forme ou je conseille sur les CSS. Besoin d'améliorer la maintenabilité ou les performances de vos projets ?