Есть ли функция JavaScript, которая может дополнить строку, чтобы получить определенную длину? - PullRequest
256 голосов
/ 22 апреля 2010

Мне нужна функция JavaScript, которая может принимать значение и дополнять его до заданной длины (мне нужны пробелы, но все, что нужно).Я нашел это:

Код:

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

Пример:

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

Но я понятия не имею, чточерт возьми, это делает, и это, кажется, не работает для меня.

Ответы [ 42 ]

487 голосов
/ 08 февраля 2013

Я нашел это решение здесь , и это для меня намного проще:

var n = 123

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

И здесь я сделал расширение для строкового объекта:

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

Пример использования:

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

Это вернет время в формате "15:30"

115 голосов
/ 25 июня 2014

более быстрый метод

Если вы делаете это несколько раз, например, для заполнения значений в массиве, и производительность является фактором, следующий подход может дать вам почти 100x преимущество по скорости ( jsPerf ) над другим решением, которое в настоящее время обсуждается на веб-сайтах. Основная идея заключается в том, что вы предоставляете функции pad полностью заполненную пустую строку для использования в качестве буфера. Функция pad просто добавляет строку для добавления к этой предварительно дополненной строке (одна строка concat), а затем нарезает или обрезает результат до желаемой длины.

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

Например, чтобы обнулить число длиной до 10 цифр,

pad('0000000000',123,true);

Для заполнения строки пробелом, чтобы вся строка состояла из 255 символов,

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

Тест производительности

См. jsPerf тест здесь .

И это также быстрее, чем ES6 string.repeat в 2 раза, как показано в пересмотренном JsPerf здесь

49 голосов
/ 22 апреля 2010

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;

}

Это намного более читабельно.

39 голосов
/ 27 марта 2013

Вот рекурсивный подход к этому.

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

Пример ...

pad(5, 'hi', '0')
=> "000hi"
33 голосов
/ 08 апреля 2016

String.prototype.padStart() и String.prototype.padEnd() в настоящее время являются кандидатами в TC39: см. github.com / tc39 / offer-string-pad-start-end (доступно только в Firefox с апреля 2016 года; a полифилл доступно).

22 голосов
/ 18 декабря 2014

Используя метод ECMAScript 6 String # repeat , функция pad настолько проста, как:

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

String#repeat в настоящее время поддерживается только в Firefox и Chrome. для другой реализации можно рассмотреть следующий простой polyfill:

String.prototype.repeat = String.prototype.repeat || function(n){ 
    return n<=1 ? this : (this + this.repeat(n-1)); 
}
22 голосов
/ 23 сентября 2017

ECMAScript 2017 добавляет метод padStart в прототип String. Этот метод дополняет строку пробелами до заданной длины. Этот метод также принимает необязательную строку, которая будет использоваться вместо пробелов для заполнения.

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

Также был добавлен метод padEnd, который работает таким же образом.

Для совместимости браузера (и полезного полифилла) см. эту ссылку .

14 голосов
/ 22 апреля 2010

Ключевой трюк в обоих этих решениях заключается в создании экземпляра array с заданным размером (на один больше, чем желаемая длина), а затем немедленном вызове метода join() для создания string. Методу join() передается заполнение string (возможно, пробелы). Поскольку array пусто, пустые ячейки будут отображаться как пустые strings в процессе объединения array в один результат string, и останется только заполнение. Это действительно хорошая техника.

14 голосов
/ 27 марта 2016

Используя метод ECMAScript 6 String # repeat и Функции стрелок , функция пэда проста как:

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

jsfiddle

редактирование: предложение из комментариев:

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

таким образом, он не выдаст ошибку, если s.length больше n

edit2: предложение из комментариев:

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

таким образом, вы можете использовать функцию как для строк, так и для не строк.

10 голосов
/ 25 января 2014

пэд со значениями по умолчанию

Я заметил, что мне в основном нужен padLeft для преобразования времени / заполнения номера

поэтому я написал эту функцию

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

Эта простая функция поддерживает Число или Строка в качестве ввода

пэд по умолчанию: 2 символа

символ по умолчанию: 0

так что я могу просто написать

padL(1);
// 01

если я добавлю второй аргумент (ширина панели)

padL(1,3);
// 001

третий параметр (pad char)

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

EDIT @BananaAcid если вы передадите неопределенное значение или строку длиной 0, вы получите 0undefined .. so:

как предложено

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

но это также может быть достигнуто более коротким способом.

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

работает также с:

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

И если вы хотите иметь возможность дополнять оба:

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

, который можно записать более коротким способом без использования слайса.

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 
)

*/

Теперь, если вы попытаетесь дополнить 'averylongword' 2 ... это не моя проблема.


Сказал, что я дам вам совет.

Большую часть времени, если вы дополняете, вы делаете это для того же значения N раз.

Использование любого типа функции внутри цикла замедляет цикл !!!

Так что, если вы просто хотите добавить несколько цифр в длинный список, не используйте функции, чтобы сделать эту простую вещь.

используйте что-то вроде этого:

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

, если вы не знаете, как максимальный размер заполнения основан на числах внутри массива.

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"
*/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...