Как я могу поместить значение с ведущими нулями?

Каков рекомендуемый способ zerofill значения в JavaScript? Я предполагаю, что я мог бы создать пользовательскую функцию, чтобы заполнить нули на значение, основанное на типе, но мне интересно, есть ли более прямой способ сделать это?

Примечание: Под "zerofilled" я подразумеваю это в смысле базы данных слова (где шестизначное нулевое представление числа 5 будет "000005" ).

Ответ 1

Примечание для читателей!

Как отмечают комментаторы, это решение является "умным", и как часто используются умные решения, интенсивность памяти и относительно медленный. Если производительность вас беспокоит, не используйте это решение!

Потенциально устаревший: 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 расширяется.

Ответ 2

Простой способ. Вы можете добавить умножение строки для пэда и превратить его в функцию.

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

Ответ 3

Я не могу поверить, что все сложные ответы здесь... Просто используйте это:

var zerofilled = ('0000'+n).slice(-4);

Ответ 4

На самом деле мне пришло в голову что-то подобное в последнее время. Я решил, что должен быть способ сделать это, не используя циклы.

Вот что я придумал.

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 с изменением журнала). Угадайте, какой из них превзошел других?:)

Ответ 5

Вот то, что я использовал для ввода номера длиной до 7 символов.

("0000000" + number).slice(-7)

Такой подход, вероятно, будет достаточным для большинства людей.

Изменение: если вы хотите сделать его более общим, вы можете сделать это:

("0".repeat(padding) + number).slice(-padding)

Изменить 2. Обратите внимание, что начиная с ES2017 вы можете использовать String.prototype.padStart:

number.toString().padStart(padding, "0")

Ответ 6

К сожалению, есть много ненужных сложных предложений для этой проблемы, как правило, включая запись собственной функции для выполнения математических или строковых манипуляций или вызова сторонней утилиты. Тем не менее, есть стандартный способ сделать это в базовой библиотеке 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() могут игнорировать любые аргументы.

Полный пример

Ответ 7

Если номер заполнения заранее известен, чтобы не превышать определенного значения, существует другой способ сделать это без циклов:

var fillZeroes = "00000000000000000000";  // max number of zero fill ever asked for in global

function zeroFill(number, width) {
    // make sure it 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/

Ответ 8

В предлагаемом (стадия 3) методе ES2017 .padStart() вы можете просто сделать это (когда реализовано/поддерживается):

string.padStart(maxLength, "0"); //max length is the max string length, not max # of fills

Ответ 9

Быстрый и грязный способ:

y = (new Array(count + 1 - x.toString().length)).join('0') + x;

При x = 5 и count = 6 у вас будет y = "000005"

Ответ 10

Вот быстрая функция, которую я придумал, чтобы выполнить эту работу. Если у кого-то есть более простой подход, не стесняйтесь делиться!

function zerofill(number, length) {
    // Setup
    var result = number.toString();
    var pad = length - result.length;

    while(pad > 0) {
        result = '0' + result;
        pad--;
    }

    return result;
}

Ответ 11

Поздно к участнику здесь, но я часто использую эту конструкцию для выполнения ad-hoc padding некоторого значения 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() nifty отрицательного индекса.

Ответ 12

Я действительно не знаю, почему, но никто не сделал это самым очевидным образом. Вот это моя реализация.

Функции:

/** Pad a number with 0 on the left */
function zeroPad(number, digits) {
    var num = number+"";
    while(num.length < digits){
        num='0'+num;
    }
    return num;
}

Prototype:

Number.prototype.zeroPad=function(digits){
    var num=this+"";
    while(num.length < digits){
        num='0'+num;
    }
    return(num);
};

Очень просто, я не могу понять, как это может быть проще. По какой-то причине я, кажется, много раз здесь, на SO, люди просто стараются избегать циклов "за" и "в то время" любой ценой. Использование regex, вероятно, будет стоить больше циклов для такого тривиального заполнения из 8 цифр.

Ответ 13

Я использую этот снайпер, чтобы получить представление из 5 цифр

(value+100000).toString().slice(-5) // "00123" with value=123

Ответ 14

Сила Math!

x = целое число для колодки
y = количество нулей для прокладки

function zeroPad(x, y)
{
   y = Math.max(y-1,0);
   var n = (x / Math.pow(10,y)).toFixed(y);
   return n.replace('.','');  
}

Ответ 16

Я не видел, чтобы кто-то указывал на то, что, когда вы используете String.prototype.substr() с отрицательным числом, которое он считает право.

Однолинейное решение вопроса ОП, 6-значное нулевое представление числа 5:

console.log(("00000000" + 5).substr(-6));

Ответ 17

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

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'

Ответ 19

Это решение ES6.

function pad(num, len) {
  return '0'.repeat(len - num.toString().length) + num;
}
alert(pad(1234,6));

Ответ 20

После долгого длительного тестирования 15 различных функций/методов, найденных в ответах на эти вопросы, теперь я знаю, что является лучшим (самым универсальным и быстрым).

Я взял 15 функций/методов из ответов на этот вопрос и сделал script для измерения времени, затраченного на выполнение 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;
}

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

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'

Ответ 21

Во всех современных браузерах вы можете использовать

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

Ответ 22

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

_.padLeft(number, 6, '0')

Ответ 23

Последний способ сделать это намного проще:

var number = 2
number.toLocaleString(undefined, {minimumIntegerDigits:2})

output: "02"

Ответ 24

Просто другое решение, но я думаю, что это более разборчиво.

function zeroFill(text, size)
{
  while (text.length < size){
  	text = "0" + text;
  }
  
  return text;
}

Ответ 25

Это менее естественный, но может быть самый быстрый...

zeroPad = function (num, count) {
    var pad = (num + '').length - count;
    while(--pad > -1) {
        num = '0' + num;
    }
    return num;
};

Ответ 26

Мое решение

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

Ответ 27

Почему бы не использовать рекурсию?

function padZero(s, n) {
    s = s.toString(); // in case someone passes a number
    return s.length >= n ? s : padZero('0' + s, n);
}

Ответ 28

Некоторые monkeypatching также работают

String.prototype.padLeft = function (n, c) {
  if (isNaN(n))
    return null;
  c = c || "0";
  return (new Array(n).join(c).substring(0, this.length-n)) + this; 
};
var paddedValue = "123".padLeft(6); // returns "000123"
var otherPadded = "TEXT".padLeft(8, " "); // returns "    TEXT"

Ответ 29

function pad(toPad, padChar, length){
    return (String(toPad).length < length)
        ? new Array(length - String(toPad).length + 1).join(padChar) + String(toPad)
        : toPad;
}

pad(5, 0, 6)= 000005

pad('10', 0, 2)= 10 // don't pad if not necessary

pad('S', 'O', 2)= SO

... и т.д..

Приветствия

Ответ 30

простейшее, наиболее прямое решение, которое вы найдете.

function zerofill(number,length) {
    var output = number.toString();
    while(output.length < length) {
      output = '0' + output;
    }
    return output;
}