307 votes

Existe-t-il une fonction JavaScript permettant de compléter une chaîne de caractères pour atteindre une longueur déterminée ?

J'ai besoin d'une fonction JavaScript qui puisse prendre une valeur et la compléter à une longueur donnée (j'ai besoin d'espaces, mais n'importe quoi ferait l'affaire). J'ai trouvé cette fonction, mais je n'ai aucune idée de ce qu'elle fait et elle ne semble pas fonctionner pour moi.

String.prototype.pad = function(l, s, t) {
  return s || (s = " "),
    (l -= this.length) > 0 ?
    (s = new Array(Math.ceil(l / s.length) + 1).join(s))
    .substr(0, t = !t ? l : t == 1 ?
      0 :
      Math.ceil(l / 2)) + this + s.substr(0, l - t) :
    this;
};

var s = "Jonas";
document.write(
  '<h2>S = '.bold(), s, "</h2>",
  'S.pad(20, "[]", 0) = '.bold(), s.pad(20, "[]", 0), "<br />",
  'S.pad(20, "[====]", 1) = '.bold(), s.pad(20, "[====]", 1), "<br />",
  'S.pad(20, "~", 2) = '.bold(), s.pad(20, "~", 2)
);

11 votes

1 votes

Comme @Aus l'a suggéré, ignorez ces anciennes réponses et utilisez simplement les "nouvelles" fonctions de rembourrage -. str.padStart(7, " ") y str.padEnd(7, " ")

0 votes

Cette réponse avec le système standard, maintenant intégré padStart y padEnd devrait être celui qui est accepté maintenant. (Présente dans tous les principaux navigateurs ; IE11 ou même des versions antérieures peuvent être polychargées).

564voto

Samuel Points 2647

EcmaScript 2017 ajouté String.padStart (avec String.padEnd ) dans ce but :

"Jonas".padStart(10); // Default pad string is a space
"42".padStart(6, "0"); // Pad with "0"
"*".padStart(8, "-/|\\"); // produces '-/|\\-/|*'

S'il n'est pas présent dans l'hôte JS, String.padStart peut être ajouté en tant que polyfill.

Pré ES-2017

J'ai trouvé cette solution ici et c'est pour moi beaucoup plus simple :

var n = 123

String("00000" + n).slice(-5); // returns 00123
("00000" + n).slice(-5); // returns 00123
("     " + n).slice(-5); // returns "  123" (with two spaces)

Et ici j'ai fait une extension à l'objet string :

String.prototype.paddingLeft = function (paddingValue) {
   return String(paddingValue + this).slice(-paddingValue.length);
};

Un exemple pour l'utiliser :

function getFormattedTime(date) {
  var hours = date.getHours();
  var minutes = date.getMinutes();

  hours = hours.toString().paddingLeft("00");
  minutes = minutes.toString().paddingLeft("00");

  return "{0}:{1}".format(hours, minutes);
};

String.prototype.format = function () {
    var args = arguments;
    return this.replace(/{(\d+)}/g, function (match, number) {
        return typeof args[number] != 'undefined' ? args[number] : match;
    });
};

Cela renverra une heure au format "15:30".

11 votes

C'est facilement l'approche la plus lisible et la plus concise que j'ai trouvée ; suffisamment simple pour que je ne m'embête généralement pas avec l'extension du prototype (au moins pour quelques utilisations seulement dans une application). Bien joué.

35 votes

Attention, cette solution raccourcira les chaînes de caractères qui sont plus longues que l'argument de la tranche (c'est-à-dire 5 caractères ici).

0 votes

Excellente solution. Cependant, comme le mentionne Denis, cela tronquera le nombre lorsqu'il sera supérieur à la valeur de remplissage. On peut facilement résoudre ce problème en découpant le plus grand des deux. Par exemple, return String(paddingValue + this).slice(-1 * Math.max(this.length, paddingValue.length)) ; } ;

128voto

Shyam Habarakada Points 2360

Une méthode plus rapide

Si vous effectuez cette opération de manière répétée, par exemple pour compléter les valeurs d'un tableau, et que les performances sont un facteur déterminant, l'approche suivante peut vous permettre d'obtenir un résultat proche de celui que vous attendiez. Avantage de 100x en vitesse ( jsPerf ) par rapport à d'autres solutions qui sont actuellement discutées sur l'internet. L'idée de base est que vous fournissez à la fonction pad une chaîne de caractères vide entièrement rembourrée à utiliser comme tampon. La fonction pad se contente d'ajouter la chaîne à ajouter à cette chaîne pré-calculée (une seule chaîne concat), puis de découper le résultat à la longueur souhaitée.

function pad(pad, str, padLeft) {
  if (typeof str === 'undefined') 
    return pad;
  if (padLeft) {
    return (pad + str).slice(-pad.length);
  } else {
    return (str + pad).substring(0, pad.length);
  }
}

Par exemple, pour mettre à zéro un nombre à 10 chiffres,

pad('0000000000',123,true);

Pour compléter une chaîne de caractères avec des espaces, de sorte que la chaîne entière compte 255 caractères,

var padding = Array(256).join(' '), // make a string of 255 spaces
pad(padding,123,true);

Test de performance

Voir le jsPerf test ici .

Et c'est plus rapide que l'ES6 string.repeat par 2 fois également, comme le montre la version révisée de JsPerf ici

Veuillez noter que jsPerf n'est plus en ligne

Veuillez noter que le site jsPerf que nous utilisions à l'origine pour évaluer les différentes méthodes n'est plus en ligne. Malheureusement, cela signifie que nous ne pouvons pas accéder aux résultats de ces tests. Triste mais vrai.

5 votes

+1 Une partie de mon problème avec StackOverflow est l'incapacité pour les modérateurs de changer les votes basés sur des réponses qui sont clairement supérieures. C'est l'un de ces cas.

1 votes

Comme quelqu'un d'autre l'a prouvé dans un jsPerf ultérieur (liens ajoutés ci-dessus), cette approche est ~ 2x plus rapide que la méthode ES6. string.repeat méthode. Si vous faites beaucoup de rembourrage de chaînes, essayez cette méthode.

6 votes

Le commentaire de Jason me laisse perplexe - en quoi cette réponse est-elle différente de celle qui a été acceptée ?

48voto

David Stratton Points 45298

http://www.webtoolkit.info/javascript_pad.html

/**
*
*  Javascript string pad
*  http://www.webtoolkit.info/
*
**/

var STR_PAD_LEFT = 1;
var STR_PAD_RIGHT = 2;
var STR_PAD_BOTH = 3;

function pad(str, len, pad, dir) {

    if (typeof(len) == "undefined") { var len = 0; }
    if (typeof(pad) == "undefined") { var pad = ' '; }
    if (typeof(dir) == "undefined") { var dir = STR_PAD_RIGHT; }

    if (len + 1 >= str.length) {

        switch (dir){

            case STR_PAD_LEFT:
                str = Array(len + 1 - str.length).join(pad) + str;
            break;

            case STR_PAD_BOTH:
                var padlen = len - str.length;
                var right = Math.ceil( padlen / 2 );
                var left = padlen - right;
                str = Array(left+1).join(pad) + str + Array(right+1).join(pad);
            break;

            default:
                str = str + Array(len + 1 - str.length).join(pad);
            break;

        } // switch

    }

    return str;

}

C'est beaucoup plus lisible.

1 votes

Ne semble pas fonctionner lorsque le pad est un espace : pad("hello", 20) = "hello "

44voto

hypno7oad Points 486

Voici une approche récursive de la question.

function pad(width, string, padding) { 
  return (width <= string.length) ? string : pad(width, padding + string, padding)
}

Un exemple...

pad(5, 'hi', '0')
=> "000hi"

8 votes

Il existe aussi une définition récursive de la multiplication des entiers... n'oubliez jamais qu'il y a une "malédiction" dans récursif...

33 votes

Il y a aussi des narvals et un type ivre dans la rue, mais aucun n'est pertinent. La malédiction de la récursion ne s'applique que lorsqu'un programmeur ne sait pas quand c'est approprié.

12 votes

"La malédiction de la récursion s'applique seulement quand un programmeur ne sait pas quand c'est approprié" ou quand ils ne réalisent pas que c'est inapproprié. Comme pour une simple fonction de remplissage de chaîne.

16voto

Carl Bosch Points 211

Merci à http://stackoverflow.com/a/14760377/555883

J'ai trouvé cette solution très courte

("0000" + valeur).slice(-4)

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