Existe uma função JavaScript que pode preencher uma string para obter um comprimento determinado?

272

Estou precisando de uma função JavaScript que possa pegar um valor e preenchê-lo em um determinado comprimento (preciso de espaços, mas qualquer coisa faria). Eu achei isto:

Código:

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;
};

Exemplo:

<script type="text/javascript">
//<![CDATA[

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)
);

//]]>
</script>

Mas eu não tenho idéia do que diabos está fazendo e não parece funcionar para mim.

Anthony Potts
fonte

Respostas:

516

Encontrei esta solução aqui e isso é para mim muito mais simples:

var n = 123

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

E aqui eu fiz uma extensão para o objeto string:

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

Um exemplo para usá-lo:

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;
    });
};

Isso retornará um horário no formato "15:30"

Samuel
fonte
11
Facilmente a abordagem mais legível e concisa que encontrei; simples o suficiente para que eu geralmente nem me incomodasse com a extensão do protótipo (pelo menos para apenas alguns usos em um aplicativo). Bem feito.
Brichins
32
Esteja ciente de que esta solução encurtará seqüências maiores do que o argumento de fatia (ou seja, 5 caracteres aqui).
Denis V
1
Oi Yaniv. Você tem uma sugestão muito boa para modificar o algoritmo. No entanto, no meu caso, os requisitos sempre precedem esse problema, porque quando tento formatar algo, sempre tenho um mínimo de especificações sobre o valor que devo tratar e, nesse caso, as especificações corrigem esse problema. Por exemplo, se eu tiver um número de telefone para formatar e manipular apenas o telefone no Canadá, validarei que o número de telefone tenha 10 caracteres antes de formatá-lo. Em qualquer caso, sua solução também é ótima. :)
Samuel
1
Se você estiver fazendo isso muito (por exemplo, preenchendo uma longa lista de valores em uma lista de algum tipo na sua página ou em outro aplicativo), veja também a resposta com o método A mais rápido em stackoverflow.com/questions/2686855/…
Shyam Habarakada
6
Isso precisa muito ser atualizado para usar as String bibliotecas JS String.padStart()e String.padEnd()para preenchimento esquerdo / direito.
SudoKid
119

Um método mais rápido

Se você estiver fazendo isso repetidamente, por exemplo, para preencher valores em uma matriz, e o desempenho for um fator, a abordagem a seguir pode oferecer quase uma vantagem de 100x na velocidade ( jsPerf ) em relação a outras soluções atualmente discutidas nas redes. A idéia básica é que você esteja fornecendo à função pad uma string vazia totalmente preenchida para usar como buffer. A função pad apenas anexa à string a ser adicionada a essa string pré-preenchida (concat de uma string) e, em seguida, corta ou corta o resultado no comprimento desejado.

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);
  }
}

Por exemplo, para zerar um número com 10 dígitos,

pad('0000000000',123,true);

Para preencher uma string com espaço em branco, a string inteira tem 255 caracteres,

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

Teste de performance

Veja o teste jsPerf aqui .

E isso é mais rápido que o ES6 string.repeatem 2x também, como mostra o JsPerf revisado aqui

Shyam Habarakada
fonte
5
+1 Parte do meu problema com o StackOverflow é a incapacidade dos moderadores de mudar votos com base em respostas claramente superiores. Este é um daqueles casos.
Jason Sebring
1
Como outra pessoa provou em um jsPerf posterior (links adicionados acima), essa abordagem é ~ 2x mais rápida que o string.repeatmétodo ES6 . Portanto, se você estiver fazendo um monte de preenchimento de cordas, definitivamente tente isso.
Shyam Habarakada
5
Estou confuso com o comentário de Jason - como essa resposta é diferente da aceita?
Corwin.amber 23/02
1
Eu olhei para o seu jsPerf. Esses testes são para sua função e algo que usa um loop while (), que nenhuma outra resposta de alta classificação usa. Não sei se isso significa que é mais rápido?
HoldOffHunger
48

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;

}

É muito mais legível.

David
fonte
1
Não parece funcionar quando a almofada é um espaço:pad("hello", 20) = "hello "
Cillié Malan 05/10
40

Aqui está uma abordagem recursiva.

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

Um exemplo...

pad(5, 'hi', '0')
=> "000hi"
hypno7oad
fonte
7
há também uma definição recursiva de multiplicação de inteiros ... lembre-se sempre que há uma 'maldição' em recursiva ...
fluxo
32
Há também narvais e um cara bêbado na rua, mas nenhum deles é relevante. A maldição da recursão só se aplica quando um programador não sabe quando é apropriado.
hypno7oad
12
"A maldição da recursão só se aplica quando um programador não sabe quando é apropriado" ou quando não percebe que é inapropriado. Tal como para uma simples função de teclado de cordas.
Danation
Isso é bastante elegante e funcionou perfeitamente para o meu caso de uso. Se você precisar preencher espaços para alinhar o texto, basta jogar o comprimento da maior seqüência de caracteres =) #
Damon Aw
12
É elegante, mas também cria uma nova string em cada iteração da função. Essa função é O (n) enquanto a solução mais popular do @Samuel é O (1). Ambos são elegantes, mas um é muito mais eficiente. Dito isto, é uma abordagem elegante e pode ser ainda mais rápida em um idioma diferente.
esmagar
40

String.prototype.padStart()e String.prototype.padEnd()atualmente são propostas de candidatos ao TC39: consulte github.com/tc39/proposal-string-pad-start-end (disponível apenas no Firefox a partir de abril de 2016; um polyfill está disponível).

ChrisV
fonte
13
Agora, com suporte por todos os navegadores (modernos): developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Sphinxxx
Para os preguiçosos: myString.padStart(padLength [, padString])emyString.padEnd(padLength [, padString])
Johan Dettmar 01/02/19
1
Adicione alguns exemplos de uso, agora que isso é suportado por todos os navegadores modernos. Isso deve ser encorajado.
Franklin Yu
Caramba, como eu não ouvi isso até hoje? Essa deve ser a resposta aceita.
electrovir 23/04
29

O ECMAScript 2017 adiciona um método padStart ao protótipo String. Este método irá preencher uma string com espaços para um determinado comprimento. Esse método também usa uma sequência opcional que será usada em vez de espaços para preenchimento.

'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo");  // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
'abc'.padStart(8, "0");     // "00000abc"
'abc'.padStart(1);          // "abc"

Também foi adicionado um método padEnd que funciona da mesma maneira.

Para compatibilidade do navegador (e um polyfill útil), consulte este link .

arMedBeta
fonte
Melhor resposta AQUI hoje em dia! 2019!
Peter Krauss
22

Usando o método ECMAScript 6, String # repeat , uma função pad é tão simples quanto:

String.prototype.padLeft = function(char, length) { 
    return char.repeat(Math.max(0, length - this.length)) + this;
}

String#repeatatualmente é suportado apenas no Firefox e Chrome. para outra implementação, pode-se considerar o seguinte polyfill simples:

String.prototype.repeat = String.prototype.repeat || function(n){ 
    return n<=1 ? this : (this + this.repeat(n-1)); 
}
Guss
fonte
Para aqueles que trabalham no Node.js, o String.repeat também é suportado lá.
Jkt123 #
15

Usando o método ECMAScript 6, String # repeat e Arrow , uma função pad é tão simples quanto:

var leftPad = (s, c, n) => c.repeat(n - s.length) + s;
leftPad("foo", "0", 5); //returns "00foo"

jsfiddle

edit: sugestão dos comentários:

const leftPad = (s, c, n) => n - s.length > 0 ? c.repeat(n - s.length) + s : s;

Dessa forma, ele não emitirá um erro quando s.lengthfor maior quen

edit2: sugestão dos comentários:

const leftPad = (s, c, n) =>{ s = s.toString(); c = c.toString(); return s.length > n ? s : c.repeat(n - s.length) + s; }

Dessa forma, você pode usar a função para cadeias e não cadeias.

InsOp
fonte
1
Isso é legal, mas se s.lengthfor maior do nque o esperado. Sugerir:let leftPad = (s, c, n) => n - s.length > 0 ? c.repeat(n - s.length) + s : s;
David G
não funciona para não-strings. Como em leftPad(12, ' ', 5). Embora eu saiba estritamente que isso pode ser bom, é provavelmente um dos casos de uso mais comuns (números de preenchimento). Talvez function leftPad(s, c, n) { s = s.toString(); return s.length > len ? s : c.repeat(n - s.length) + s; }. Usar os functionmeios leftPad pode estar na parte inferior do arquivo. Caso contrário, você provavelmente constnão deve usar nem varnem let.
gman
@ gman, obrigado por esta sugestão, mas qual é a sua variável len?
InsOp 13/03/2019
Doh, lendeveria sern
gman 13/03
14

O principal truque nessas duas soluções é criar uma arrayinstância com um determinado tamanho (um a mais que o comprimento desejado) e, em seguida, chamar imediatamente o join()método para criar a string. O join()método é passado no preenchimento string(espaços provavelmente). Como o campo arrayestá vazio, as células vazias serão renderizadas como vazias stringsdurante o processo de união do arrayresultado em um stringe apenas o preenchimento permanecerá. É uma técnica muito boa.

Pontudo
fonte
10

bloco com valores padrão

Notei que eu principalmente preciso do padLeft para conversão de tempo / preenchimento de número

então eu escrevi essa função

function padL(a,b,c){//string/number,length=2,char=0
 return (new Array(b||2).join(c||0)+a).slice(-b)
}

Esta função simples suporta Number ou String como entrada

pad padrão é 2 caracteres

o padrão é 0

então eu posso simplesmente escrever

padL(1);
// 01

se eu adicionar o segundo argumento (largura do bloco)

padL(1,3);
// 001

terceiro parâmetro (pad char)

padL('zzz',10,'x');
// xxxxxxxzzz

EDIT @BananaAcid se você passar um valor indefinido ou uma string de 0, obtém .. so 0undefined:

como sugerido

function padL(a,b,c){//string/number,length=2,char=0
 return (new Array((b||1)+1).join(c||0)+(a||'')).slice(-(b||2))
}

mas isso também pode ser alcançado de maneira mais curta.

function padL(a,b,c){//string/number,length=2,char=0
 return (new Array(b||2).join(c||0)+(a||c||0)).slice(-b)
}

trabalha também com:

padL(0)
padL(NaN)
padL('')
padL(undefined)
padL(false)

E se você deseja poder de ambos os modos:

function pad(a,b,c,d){//string/number,length=2,char=0,0/false=Left-1/true=Right
return a=(a||c||0),c=new Array(b||2).join(c||0),d?(a+c).slice(0,b):(c+a).slice(-b)
}

que pode ser escrito de maneira mais curta sem usar fatia.

function pad(a,b,c,d){
 return a=(a||c||0)+'',b=new Array((++b||3)-a.length).join(c||0),d?a+b:b+a
}
/*

Usage:

pad(
 input // (int or string) or undefined,NaN,false,empty string
       // default:0 or PadCharacter
 // optional
 ,PadLength // (int) default:2
 ,PadCharacter // (string or int) default:'0'
 ,PadDirection // (bolean) default:0 (padLeft) - (true or 1) is padRight 
)

*/

Agora, se você tentar preencher 'averylongword' com 2 ... isso não é problema meu.


Disse que eu te dou uma dica.

Na maioria das vezes, se você o pressiona, o mesmo valor N vezes.

Usar qualquer tipo de função dentro de um loop diminui o ciclo !!!

Portanto, se você quiser deixar alguns números em uma longa lista, não use funções para fazer isso de maneira simples.

use algo como isto:

var arrayOfNumbers=[1,2,3,4,5,6,7],
    paddedArray=[],
    len=arrayOfNumbers.length;
while(len--){
 paddedArray[len]=('0000'+arrayOfNumbers[len]).slice(-4);
}

se você não souber como o tamanho máximo de preenchimento é baseado nos números dentro da matriz.

var arrayOfNumbers=[1,2,3,4,5,6,7,49095],
    paddedArray=[],
    len=arrayOfNumbers.length;

// search the highest number
var arrayMax=Function.prototype.apply.bind(Math.max,null),
// get that string length
padSize=(arrayMax(arrayOfNumbers)+'').length,
// create a Padding string
padStr=new Array(padSize).join(0);
// and after you have all this static values cached start the loop.
while(len--){
 paddedArray[len]=(padStr+arrayOfNumbers[len]).slice(-padSize);//substr(-padSize)
}
console.log(paddedArray);

/*
0: "00001"
1: "00002"
2: "00003"
3: "00004"
4: "00005"
5: "00006"
6: "00007"
7: "49095"
*/
cocco
fonte
Muito agradável! Veio com o mesmo resultado, apenas como uma observação: isso concata a string com o comprimento máximo especificado e uma string vazia será um caractere muito curto e strings indefinidas resultarão no uso de "undefined", bem como na emenda poderá gerar um erro - combinado. return (new Array((b||1)+1).join(c||0)+(a||'')).slice(-(b||2)). E como sempre: vocês por aí, não copiem apenas o código que não entendem.
precisa saber é o seguinte
1
(new Array (B || 2) .join (c || 0) + (a || c || 0)) slice (-b) ... mais curto.
Cocco
9

Tomando as idéias de Samuel, aqui em cima. E lembre-se de um script SQL antigo, tentei com isso:

a=1234;
'0000'.slice(a.toString().length)+a;

Funciona em todos os casos que eu poderia imaginar:

a=     1 result  0001
a=    12 result  0012
a=   123 result  0123
a=  1234 result  1234
a= 12345 result 12345
a=  '12' result  0012
Alejandro Illecas
fonte
5

A string de preenchimento foi implementada na nova versão javascript.

str.padStart(targetLength [, padString])

https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/String/padStart

Se você deseja sua própria função, verifique este exemplo:

const myString = 'Welcome to my house';
String.prototype.padLeft = function(times = 0, str = ' ') {
    return (Array(times).join(str) + this);
}
console.log(myString.padLeft(12, ':'));
//:::::::::::Welcome to my house
daronwolff
fonte
Esta resposta foi mencionada por várias outras respostas, por isso é uma duplicata que não adiciona novas informações. Por favor, pesquise antes de responder.
Franklin Yu
Este é o primeiro com a assinatura completa. E deve ser a única resposta a partir de hoje.
d_f
4

Aqui está uma função simples que eu uso.

var pad=function(num,field){
    var n = '' + num;
    var w = n.length;
    var l = field.length;
    var pad = w < l ? l-w : 0;
    return field.substr(0,pad) + n;
};

Por exemplo:

pad    (20,'     ');    //   20
pad   (321,'     ');    //  321
pad (12345,'     ');    //12345
pad (   15,'00000');    //00015
pad (  999,'*****');    //**999
pad ('cat','_____');    //__cat  
Daniel LaFavers
fonte
4

Um caminho curto:

(x=>(new Array(int-x.length+1)).join(char)+x)(String)

Exemplo:

(x=>(new Array(6-x.length+1)).join("0")+x)("1234")

retorno: "001234"

Matias Dominguez
fonte
1
talvez String.prototype.padStart()devesse ser mais fácil.
Max Peng
3

O es7 é apenas rascunhos e propostas no momento, mas se você deseja acompanhar a compatibilidade com as especificações, suas funções de bloco precisam:

  1. Suporte para teclado com vários caracteres.
  2. Não trunque a sequência de entrada
  3. O padrão do teclado é o espaço

Da minha biblioteca de polyfill, mas aplique sua própria diligência para extensões de protótipo.

// Tests
'hello'.lpad(4) === 'hello'
'hello'.rpad(4) === 'hello'
'hello'.lpad(10) === '     hello'
'hello'.rpad(10) === 'hello     '
'hello'.lpad(10, '1234') === '41234hello'
'hello'.rpad(10, '1234') === 'hello12341'

String.prototype.lpad || (String.prototype.lpad = function( length, pad )
{
    if( length < this.length ) return this;

    pad = pad || ' ';
    let str = this;

    while( str.length < length )
    {
        str = pad + str;
    }

    return str.substr( -length );
});

String.prototype.rpad || (String.prototype.rpad = function( length, pad )
{
    if( length < this.length ) return this;

    pad = pad || ' ';
    let str = this;

    while( str.length < length )
    {
        str += pad;
    }

    return str.substr( 0, length );
});
Adria
fonte
3

Aqui está uma resposta simples em basicamente uma linha de código.

var value = 35 // the numerical value
var x = 5 // the minimum length of the string

var padded = ("00000" + value).substr(-x);

Certifique-se de que o número de caracteres em seu preenchimento, zeros aqui, seja pelo menos o comprimento mínimo pretendido. Então, realmente, para colocá-lo em uma linha, obter um resultado de "00035" neste caso é:

var padded = ("00000" + 35).substr(-5);
Jack Thomson
fonte
2

As manipulações de matriz são realmente lentas se comparadas a concatenações simples de strings. Obviamente, faça referência ao seu caso de uso.

function(string, length, pad_char, append) {
    string = string.toString();
    length = parseInt(length) || 1;
    pad_char = pad_char || ' ';

    while (string.length < length) {
        string = append ? string+pad_char : pad_char+string;
    }
    return string;
};
será Farrell
fonte
2

Uma variante da resposta de @Daniel LaFavers .

var mask = function (background, foreground) {
  bg = (new String(background));
  fg = (new String(foreground));
  bgl = bg.length;
  fgl = fg.length;
  bgs = bg.substring(0, Math.max(0, bgl - fgl));
  fgs = fg.substring(Math.max(0, fgl - bgl));
  return bgs + fgs;
};

Por exemplo:

mask('00000', 11  );   // '00011'
mask('00011','00' );   // '00000'
mask( 2     , 3   );   // '3'
mask('0'    ,'111');   // '1'
mask('fork' ,'***');   // 'f***'
mask('_____','dog');   // '__dog'
Akseli Palén
fonte
2

Estamos em 2014 e sugiro uma função de preenchimento de string Javascript. Ha!

Ossos nus: almofada direita com espaços

function pad ( str, length ) {
    var padding = ( new Array( Math.max( length - str.length + 1, 0 ) ) ).join( " " );
    return str + padding;
}

Fantasia: almofada com opções

/**
 * @param {*}       str                         input string, or any other type (will be converted to string)
 * @param {number}  length                      desired length to pad the string to
 * @param {Object}  [opts]
 * @param {string}  [opts.padWith=" "]          char to use for padding
 * @param {boolean} [opts.padLeft=false]        whether to pad on the left
 * @param {boolean} [opts.collapseEmpty=false]  whether to return an empty string if the input was empty
 * @returns {string}
 */
function pad ( str, length, opts ) {
    var padding = ( new Array( Math.max( length - ( str + "" ).length + 1, 0 ) ) ).join( opts && opts.padWith || " " ),
        collapse = opts && opts.collapseEmpty && !( str + "" ).length;
    return collapse ? "" : opts && opts.padLeft ? padding + str : str + padding;
}

Uso (fantasia):

pad( "123", 5 );
// returns "123  "

pad( 123, 5 );
// returns "123  " - non-string input

pad( "123", 5, { padWith: "0", padLeft: true } );
// returns "00123"

pad( "", 5 );
// returns "     "

pad( "", 5, { collapseEmpty: true } );
// returns ""

pad( "1234567", 5 );
// returns "1234567"
hashchange
fonte
2

Eu acho que é melhor evitar recursão porque é caro.

function padLeft(str,size,padwith) {
	if(size <= str.length) {
        // not padding is required.
		return str;
	} else {
        // 1- take array of size equal to number of padding char + 1. suppose if string is 55 and we want 00055 it means we have 3 padding char so array size should be 3 + 1 (+1 will explain below)
        // 2- now join this array with provided padding char (padwith) or default one ('0'). so it will produce '000'
        // 3- now append '000' with orginal string (str = 55), will produce 00055

        // why +1 in size of array? 
        // it is a trick, that we are joining an array of empty element with '0' (in our case)
        // if we want to join items with '0' then we should have at least 2 items in the array to get joined (array with single item doesn't need to get joined).
        // <item>0<item>0<item>0<item> to get 3 zero we need 4 (3+1) items in array   
		return Array(size-str.length+1).join(padwith||'0')+str
	}
}

alert(padLeft("59",5) + "\n" +
     padLeft("659",5) + "\n" +
     padLeft("5919",5) + "\n" +
     padLeft("59879",5) + "\n" +
     padLeft("5437899",5));

Sheikh Abdul Wahid
fonte
1

Aqui está uma função JavaScript que adiciona um número especificado de preenchimentos com symble personalizado. a função usa três parâmetros.

    padMe -> string ou número no pad esquerdo
    almofadas -> número de almofadas
    padSymble -> symble personalizado, o padrão é "0" 

    function leftPad(padMe, pads, padSymble) {
         if( typeof padMe === "undefined") {
             padMe = "";
         }
         if (typeof pads === "undefined") {
             pads = 0;
         }
         if (typeof padSymble === "undefined") {
             padSymble = "0";
         }

         var symble = "";
         var result = [];
         for(var i=0; i < pads ; i++) {
            symble += padSymble;
         }
        var length = symble.length - padMe.toString().length;
        result = symble.substring(0, length);
        return result.concat(padMe.toString());
    }
/ * Aqui estão alguns resultados:

> leftPad (1)
"1"
> leftPad (1, 4)
"0001"
> leftPad (1, 4, "0")
"0001"
> leftPad (1, 4, "@")
"@@@ 1"

* /
yantaq
fonte
1
/**************************************************************************************************
Pad a string to pad_length fillig it with pad_char.
By default the function performs a left pad, unless pad_right is set to true.

If the value of pad_length is negative, less than, or equal to the length of the input string, no padding takes place.
**************************************************************************************************/
if(!String.prototype.pad)
String.prototype.pad = function(pad_char, pad_length, pad_right) 
{
   var result = this;
   if( (typeof pad_char === 'string') && (pad_char.length === 1) && (pad_length > this.length) )
   {
      var padding = new Array(pad_length - this.length + 1).join(pad_char); //thanks to http://stackoverflow.com/questions/202605/repeat-string-javascript/2433358#2433358
      result = (pad_right ? result + padding : padding + result);
   }
   return result;
}

E então você pode fazer:

alert( "3".pad("0", 3) ); //shows "003"
alert( "hi".pad(" ", 3) ); //shows " hi"
alert( "hi".pad(" ", 3, true) ); //shows "hi "
Marco Demaio
fonte
Não mexa com os protótipos!
precisa
1

Se você quiser apenas uma linha de hacky muito simples para preencher, basta criar uma sequência do caractere de preenchimento desejado com o comprimento máximo de preenchimento desejado e, em seguida, colocar a substring no comprimento do que você deseja preencher.

Exemplo: preencher o armazenamento de cadeias ecom espaços com 25 caracteres.

var e = "hello"; e = e + "                         ".substring(e.length)

Resultado: "hello "

Se você quiser fazer o mesmo com um número como entrada, basta ligar .toString()antes.

qwertzguy
fonte
Isso é realmente muito legal, não como uma função de uso geral - mas eu pude ver isso como um hack válido em alguns contextos para salvar um loop.
Ankr
Idéia interessante. @ankr Para usá-lo como uma função de uso geral, você pode Array(n).join(c)configurar o comprimento e o caractere do preenchimento, por exemplo Array(26).join(' ').
precisa saber é o seguinte
1

ainda outra abordagem com a combinação de algumas soluções

/**
 * pad string on left
 * @param {number} number of digits to pad, default is 2
 * @param {string} string to use for padding, default is '0' *
 * @returns {string} padded string
 */
String.prototype.paddingLeft = function (b,c) {
    if (this.length > (b||2))
        return this+'';
  return (this||c||0)+'',b=new Array((++b||3)-this.length).join(c||0),b+this
};

/**
 * pad string on right
 * @param {number} number of digits to pad, default is 2
 * @param {string} string to use for padding, default is '0' *
 * @returns {string} padded string
 */
String.prototype.paddingRight = function (b,c) {
  if (this.length > (b||2))
        return this+'';
  return (this||c||0)+'',b=new Array((++b||3)-this.length).join(c||0),this+b
};    
Jeremias
fonte
1

Um amigo perguntou sobre o uso de uma função JavaScript para pressionar para a esquerda. Isso se transformou em um pouco de esforço entre alguns de nós no bate-papo para codificá-lo. Este foi o resultado:

function l(p,t,v){
    v+="";return v.length>=t?v:l(p,t,p+v); 
}

Ele garante que o valor a ser preenchido seja uma sequência e, se não for o comprimento do comprimento total desejado, ele será preenchido uma vez e depois será recursivo. Aqui está o que parece com uma nomeação e estrutura mais lógicas

function padLeft(pad, totalLength, value){
    value = value.toString();

    if( value.length >= totalLength ){
        return value;
    }else{
        return padLeft(pad, totalLength, pad + value);
    }
}

O exemplo que estávamos usando era garantir que os números fossem preenchidos 0à esquerda para formar um comprimento máximo de 6. Aqui está um exemplo:

function l(p,t,v){v+="";return v.length>=t?v:l(p,t,p+v);}

var vals = [6451,123,466750];

var pad = l(0,6,vals[0]);// pad with 0's, max length 6

var pads = vals.map(function(i){ return l(0,6,i) });

document.write(pads.join("<br />"));

Travis J
fonte
1

Um pouco tarde, mas pensei que eu poderia compartilhar de qualquer maneira. Achei útil adicionar uma extensão de protótipo ao Object. Dessa forma, posso digitar números e seqüências de caracteres, esquerda ou direita. Eu tenho um módulo com utilitários semelhantes que incluo nos meus scripts.

// include the module in your script, there is no need to export
var jsAddOns = require('<path to module>/jsAddOns');

~~~~~~~~~~~~ jsAddOns.js ~~~~~~~~~~~~

/* 
 * method prototype for any Object to pad it's toString()
 * representation with additional characters to the specified length
 *
 * @param padToLength required int
 *     entire length of padded string (original + padding)
 * @param padChar optional char
 *     character to use for padding, default is white space
 * @param padLeft optional boolean
 *     if true padding added to left
 *     if omitted or false, padding added to right
 *
 * @return padded string or
 *     original string if length is >= padToLength
 */
Object.prototype.pad = function(padToLength, padChar, padLeft) {    

    // get the string value
    s = this.toString()

    // default padToLength to 0
    // if omitted, original string is returned
    padToLength = padToLength || 0;

    // default padChar to empty space
    padChar = padChar || ' ';


    // ignore padding if string too long
    if (s.length >= padToLength) {
        return s;
    }

    // create the pad of appropriate length
    var pad = Array(padToLength - s.length).join(padChar);

    // add pad to right or left side
    if (padLeft) {
        return pad  + s;        
    } else {
        return s + pad;
    }
};
user5925630
fonte
1
  1. Nunca insira dados em algum lugar (especialmente não no começo, como str = pad + str;), pois os dados serão realocados toda vez. Anexar sempre no final!
  2. Não coloque sua corda no laço. Deixe-o em paz e construa sua corda de pad primeiro. No final, concatene-o com sua string principal.
  3. Não atribua string de preenchimento toda vez (como str += pad;). É muito mais rápido anexar a string de preenchimento a ela mesma e extrair os primeiros x-chars (o analisador pode fazer isso com eficiência se você extrair do primeiro char). Isso é crescimento exponencial, o que significa que desperdiça alguma memória temporariamente (você não deve fazer isso com textos extremamente grandes).

if (!String.prototype.lpad) {
    String.prototype.lpad = function(pad, len) {
        while (pad.length < len) {
            pad += pad;
        }
        return pad.substr(0, len-this.length) + this;
    }
}

if (!String.prototype.rpad) {
    String.prototype.rpad = function(pad, len) {
        while (pad.length < len) {
            pad += pad;
        }
        return this + pad.substr(0, len-this.length);
    }
}

StanE
fonte
0

Aqui está minha opinião

Não tenho tanta certeza sobre o desempenho, mas acho muito mais legível do que outras opções que vi por aqui ...

var replicate = function(len, char) {
  return Array(len+1).join(char || ' ');
};

var padr = function(text, len, char) {
  if (text.length >= len) return text;
  return text + replicate(len-text.length, char);
};
opensas
fonte