Как я могу дополнить значение ведущими нулями?
Каков рекомендуемый способ обнуления значения в JavaScript? Я полагаю, что мог бы создать пользовательскую функцию для добавления нулей к типизированному значению, но мне интересно, есть ли более прямой способ сделать это?
Примечание. Под "заполненным нулями" я подразумеваю это в смысле слова в базе данных (где 6-значное представление с нулевым заполнением числа 5 будет "000005").
79 ответов
Примечание для читателей!
Как отметили комментаторы, это решение "умное", и, как это часто бывает с умными решениями, оно потребляет много памяти и относительно медленно. Если производительность вас беспокоит, не используйте это решение!
Потенциально устаревший: ECMAScript 2017 включает в себя String.prototype.padStart, а Number.prototype.toLocaleString существует с версии ECMAScript 3.1. Пример:
var n=-0.1; n.toLocaleString('en', {minimumIntegerDigits:4,minimumFractionDigits:2,useGrouping:false})
... выдаст "-0000.10".
// or const padded = (.1+"").padStart(6,"0"); `-${padded}`
... выдаст "-0000.1".
Простая функция - это все, что вам нужно
function zeroFill( number, width )
{
width -= number.toString().length;
if ( width > 0 )
{
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
}
return number + ""; // always return a string
}
Вы могли бы испечь это в библиотеке, если вы хотите сохранить пространство имен или что-то еще. Как с расширением jQuery.
Я не могу поверить, что все сложные ответы здесь... Просто используйте это:
var zerofilled = ('0000'+n).slice(-4);
Простой способ. Вы можете добавить умножение строк для пэда и превратить его в функцию.
var pad = "000000";
var n = '5';
var result = (pad+n).slice(-pad.length);
Как функция,
function paddy(num, padlen, padchar) {
var pad_char = typeof padchar !== 'undefined' ? padchar : '0';
var pad = new Array(1 + padlen).join(pad_char);
return (pad + num).slice(-pad.length);
}
var fu = paddy(14, 5); // 00014
var bar = paddy(2, 4, '#'); // ###2
Я действительно должен был придумать что-то подобное в последнее время. Я подумал, что должен быть способ сделать это без использования петель.
Это то, что я придумал.
function zeroPad(num, numZeros) {
var n = Math.abs(num);
var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
var zeroString = Math.pow(10,zeros).toString().substr(1);
if( num < 0 ) {
zeroString = '-' + zeroString;
}
return zeroString+n;
}
Затем просто используйте его, предоставив число для нуля:
> zeroPad(50,4);
"0050"
Если число больше, чем заполнение, число будет выходить за пределы заполнения:
> zeroPad(51234, 3);
"51234"
Десятичные числа тоже хорошо!
> zeroPad(51.1234, 4);
"0051.1234"
Если вы не против загрязнения глобального пространства имен, вы можете добавить его в Number напрямую:
Number.prototype.leftZeroPad = function(numZeros) {
var n = Math.abs(this);
var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
var zeroString = Math.pow(10,zeros).toString().substr(1);
if( this < 0 ) {
zeroString = '-' + zeroString;
}
return zeroString+n;
}
И если вы хотите, чтобы десятичные дроби занимали место в отступе:
Number.prototype.leftZeroPad = function(numZeros) {
var n = Math.abs(this);
var zeros = Math.max(0, numZeros - n.toString().length );
var zeroString = Math.pow(10,zeros).toString().substr(1);
if( this < 0 ) {
zeroString = '-' + zeroString;
}
return zeroString+n;
}
Ура!
XDR логарифмическое изменение, которое, кажется, работает лучше.
ВНИМАНИЕ: эта функция завершается ошибкой, если num равно нулю (например, zeropad(0, 2))
function zeroPad (num, numZeros) {
var an = Math.abs (num);
var digitCount = 1 + Math.floor (Math.log (an) / Math.LN10);
if (digitCount >= numZeros) {
return num;
}
var zeroString = Math.pow (10, numZeros - digitCount).toString ().substr (1);
return num < 0 ? '-' + zeroString + an : zeroString + an;
}
Говоря о производительности, tomsmeding сравнил 3 лучших ответа ( 4 с вариацией журнала). Угадайте, какой из них превзошел два других?:)
В предлагаемом (этап 3) метод ES2017 .padStart()
теперь вы можете просто сделать (когда реализовано / поддерживается):
string.padStart(maxLength, "0"); //max length is the max string length, not max # of fills
Вот что я использовал, чтобы набрать номер длиной до 7 символов.
("0000000" + number).slice(-7)
Такой подход, вероятно, будет достаточно для большинства людей.
Изменить: Если вы хотите сделать его более общим, вы можете сделать это:
("0".repeat(padding) + number).slice(-padding)
К сожалению, существует множество ненужных сложных предложений для этой проблемы, обычно включающих написание собственной функции для выполнения математических или строковых операций или вызова сторонней утилиты. Тем не менее, есть стандартный способ сделать это в базовой библиотеке JavaScript с помощью только одной строки кода. Возможно, стоит обернуть эту строку кода в функцию, чтобы не указывать параметры, которые вы никогда не захотите изменить, например, локальное имя или стиль.
var amount = 5;
var text = amount.toLocaleString('en-US',
{
style: 'decimal',
minimumIntegerDigits: 3,
useGrouping: false
});
Это даст значение "005" для текста. Вы также можете использовать функцию toLocaleString для Number, чтобы заполнить нули справа от десятичной точки.
var amount = 5;
var text = amount.toLocaleString('en-US',
{
style: 'decimal',
minimumFractionDigits: 2,
useGrouping: false
});
Это даст значение "5,00" для текста. Измените useGrouping на true, чтобы использовать запятые для тысяч.
Обратите внимание, что с помощью toLocaleString()
с locales
а также options
аргументы стандартизированы отдельно в ECMA-402, а не в ECMAScript. На сегодняшний день в некоторых браузерах реализована только базовая поддержка, т.е. toLocaleString()
может игнорировать любые аргументы.
Если заранее известно, что номер заполнения не превышает определенного значения, есть другой способ сделать это без циклов:
var fillZeroes = "00000000000000000000"; // max number of zero fill ever asked for in global
function zeroFill(number, width) {
// make sure it's a string
var input = number + "";
var prefix = "";
if (input.charAt(0) === '-') {
prefix = "-";
input = input.slice(1);
--width;
}
var fillAmt = Math.max(width - input.length, 0);
return prefix + fillZeroes.slice(0, fillAmt) + input;
}
Тестовые случаи здесь: http://jsfiddle.net/jfriend00/N87mZ/
Быстрый и грязный способ:
y = (new Array(count + 1 - x.toString().length)).join('0') + x;
Для x = 5 и count = 6 у вас будет y = "000005"
Вот быстрая функция, которую я придумал, чтобы сделать работу. Если у кого-то есть более простой подход, не стесняйтесь делиться!
function zerofill(number, length) {
// Setup
var result = number.toString();
var pad = length - result.length;
while(pad > 0) {
result = '0' + result;
pad--;
}
return result;
}
ECMAScript 2017: используйте padStart или padEnd
'abc'.padStart(10); // " abc"
'abc'.padStart(10, "foo"); // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"
Больше информации:
Опоздал на вечеринку, но я часто использую эту конструкцию для произвольного заполнения некоторой ценности n
, известный как положительный, десятичный:
(offset + n + '').substr(1);
куда offset
10^^ цифр.
Например, заполнение до 5 цифр, где n = 123:
(1e5 + 123 + '').substr(1); // => 00123
Шестнадцатеричная версия этого немного более многословна:
(0x100000 + 0x123).toString(16).substr(1); // => 00123
Примечание 1: Мне также нравится решение @profitehlolz, которое является строковой версией этого, используя изящную функцию отрицательного индекса slice().
Я использую этот фрагмент, чтобы получить представление из 5 цифр
(value+100000).toString().slice(-5) // "00123" with value=123
Я действительно не знаю почему, но никто не сделал это самым очевидным способом. Вот моя реализация.
Функция:
/** Pad a number with 0 on the left */
function zeroPad(number, digits) {
var num = number+"";
while(num.length < digits){
num='0'+num;
}
return num;
}
Прототип:
Number.prototype.zeroPad=function(digits){
var num=this+"";
while(num.length < digits){
num='0'+num;
}
return(num);
};
Очень просто, я не могу понять, как это может быть проще. По какой-то причине я, кажется, много раз здесь на SO, люди просто пытаются избежать циклов for и while любой ценой. Использование регулярных выражений, вероятно, будет стоить гораздо больше циклов для такого тривиального заполнения из 8 цифр.
Во всех современных браузерах вы можете использовать
numberStr.padStart(numberLength, "0");
function zeroFill(num, numLength) {
var numberStr = num.toString();
return numberStr.padStart(numLength, "0");
}
var numbers = [0, 1, 12, 123, 1234, 12345];
numbers.forEach(
function(num) {
var numString = num.toString();
var paddedNum = zeroFill(numString, 5);
console.log(paddedNum);
}
);
Вот ссылка на MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
Сила математики!
x = целое число для заполнения
y = количество нулей для заполнения
function zeroPad(x, y)
{
y = Math.max(y-1,0);
var n = (x / Math.pow(10,y)).toFixed(y);
return n.replace('.','');
}
Не изобретайте колесо, используйте строку подчеркивания:
var numToPad = '5';
alert(_.str.pad(numToPad, 6, '0')); // yields: '000005'
Я не видел, чтобы кто-то указывал на тот факт, что когда вы используете String.prototype.substr() с отрицательным числом, это считается справа.
Единственное решение вопроса ОП, 6-значное представление числа 5 с нулевым заполнением:
console.log(("00000000" + 5).substr(-6));
Обобщая, мы получим:
function pad(num, len) { return ("00000000" + num).substr(-len) };
console.log(pad(5, 6));
console.log(pad(45, 6));
console.log(pad(345, 6));
console.log(pad(2345, 6));
console.log(pad(12345, 6));
Это решение ES6.
function pad(num, len) {
return '0'.repeat(len - num.toString().length) + num;
}
alert(pad(1234,6));
Не то чтобы на этот вопрос требовалось больше ответов, но я подумал, что добавлю простую версию lodash.
_.padLeft(number, 6, '0')
Первый параметр - это любое действительное число, второй параметр - положительное целое число, указывающее минимальное количество цифр слева от десятичной точки, а третий параметр - необязательное положительное целое число, указывающее число, если цифры находятся справа от десятичной точки.
function zPad(n, l, r){
return(a=String(n).match(/(^-?)(\d*)\.?(\d*)/))?a[1]+(Array(l).join(0)+a[2]).slice(-Math.max(l,a[2].length))+('undefined'!==typeof r?(0<r?'.':'')+(a[3]+Array(r+1).join(0)).slice(0,r):a[3]?'.'+a[3]:''):0
}
так
zPad(6, 2) === '06'
zPad(-6, 2) === '-06'
zPad(600.2, 2) === '600.2'
zPad(-600, 2) === '-600'
zPad(6.2, 3) === '006.2'
zPad(-6.2, 3) === '-006.2'
zPad(6.2, 3, 0) === '006'
zPad(6, 2, 3) === '06.000'
zPad(600.2, 2, 3) === '600.200'
zPad(-600.1499, 2, 3) === '-600.149'
После долгого и долгого тестирования 15 различных функций / методов, найденных в ответах на эти вопросы, я теперь знаю, какой из них самый лучший (самый универсальный и быстрый).
Я взял 15 функций / методов из ответов на этот вопрос и создал сценарий для измерения времени выполнения 100 пэдов. Каждый блокнот будет дополнять номер 9
с 2000
нули. Это может показаться чрезмерным, и это так, но это дает вам хорошее представление о масштабировании функций.
Код, который я использовал, можно найти здесь: https://gist.github.com/NextToNothing/6325915
Не стесняйтесь изменять и тестировать код самостоятельно.
Чтобы получить самый универсальный метод, вы должны использовать цикл. Это потому, что с очень большим количеством других, вероятно, потерпит неудачу, в то время как, это будет успешно.
Итак, какой цикл использовать? Ну, это было бы while
петля. for
цикл все еще быстрый, но while
Цикл только немного быстрее (пара мс) - и чище.
Подобные ответы Wilco
, Aleksandar Toplek
или же Vitim.us
сделает работу отлично.
Лично я попробовал другой подход. Я пытался использовать рекурсивную функцию для заполнения строки / числа. Он работал лучше, чем методы, соединяющие массив, но, тем не менее, работал не так быстро, как цикл for.
Моя функция:
function pad(str, max, padder) {
padder = typeof padder === "undefined" ? "0" : padder;
return str.toString().length < max ? pad(padder.toString() + str, max, padder) : str;
}
Вы можете использовать мою функцию с настройкой переменной padding или без нее. Ну вот так:
pad(1, 3); // Returns '001'
// - Or -
pad(1, 3, "x"); // Returns 'xx1'
Лично после тестов я бы использовал метод с циклом while, например Aleksandar Toplek
или же Vitim.us
, Тем не менее, я бы немного изменил его, чтобы вы могли установить строку заполнения.
Итак, я бы использовал этот код:
function padLeft(str, len, pad) {
pad = typeof pad === "undefined" ? "0" : pad + "";
str = str + "";
while(str.length < len) {
str = pad + str;
}
return str;
}
// Usage
padLeft(1, 3); // Returns '001'
// - Or -
padLeft(1, 3, "x"); // Returns 'xx1'
Вы также можете использовать его как функцию-прототип, используя этот код:
Number.prototype.padLeft = function(len, pad) {
pad = typeof pad === "undefined" ? "0" : pad + "";
var str = this + "";
while(str.length < len) {
str = pad + str;
}
return str;
}
// Usage
var num = 1;
num.padLeft(3); // Returns '001'
// - Or -
num.padLeft(3, "x"); // Returns 'xx1'
Последний способ сделать это намного проще:
var number = 2
number.toLocaleString(undefined, {minimumIntegerDigits:2})
output: "02"
Просто другое решение, но я думаю, что оно более разборчиво.
function zeroFill(text, size)
{
while (text.length < size){
text = "0" + text;
}
return text;
}
С ES6 + JavaScript:
Вы можете "обнулить число" с помощью следующей функции:
/**
* @param number The number
* @param minLength Minimal length for your string with leading zeroes
* @return Your formatted string
*/
function zerofill(nb, minLength) {
// Convert your number to string.
let nb2Str = nb.toString()
// Guess the number of zeroes you will have to write.
let nbZeroes = Math.max(0, minLength - nb2Str.length)
// Compute your result.
return `${ '0'.repeat(nbZeroes) }${ nb2Str }`
}
console.log(zerofill(5, 6)) // Displays "000005"
С ES2017+:
/**
* @param number The number
* @param minLength Minimal length for your string with leading zeroes
* @return Your formatted string
*/
const zerofill = (nb, minLength) => nb.toString().padStart(minLength, '0')
console.log(zerofill(5, 6)) // Displays "000005"
Мое решение
Number.prototype.PadLeft = function (length, digit) {
var str = '' + this;
while (str.length < length) {
str = (digit || '0') + str;
}
return str;
};
использование
var a = 567.25;
a.PadLeft(10); // 0000567.25
var b = 567.25;
b.PadLeft(20, '2'); // 22222222222222567.25
Этот менее родной, но может быть самым быстрым...
zeroPad = function (num, count) {
var pad = (num + '').length - count;
while(--pad > -1) {
num = '0' + num;
}
return num;
};
Самое простое, самое простое решение, которое вы найдете.
function zerofill(number,length) {
var output = number.toString();
while(output.length < length) {
output = '0' + output;
}
return output;
}
Почему бы не использовать рекурсию?
function padZero(s, n) {
s = s.toString(); // in case someone passes a number
return s.length >= n ? s : padZero('0' + s, n);
}
Просто для удовольствия, вот моя версия функции пэда:
function pad(num, len) {
return Array(len + 1 - num.toString().length).join('0') + num;
}
Это также не будет усекать числа длиннее, чем длина заполнения