Wie kann ich einen Wert mit führenden Nullen auffüllen?

395

Was ist die empfohlene Methode, um einen Wert in JavaScript auf Null zu setzen? Ich stelle mir vor, ich könnte eine benutzerdefinierte Funktion erstellen, um Nullen auf einen typisierten Wert aufzufüllen, aber ich frage mich, ob es einen direkteren Weg gibt, dies zu tun?

Hinweis: Mit "nullgefüllt" meine ich es im Datenbank-Sinne des Wortes (wobei eine 6-stellige nullgefüllte Darstellung der Zahl 5 "000005" wäre).

Wilco
quelle
Dies sind wirklich nicht genug Informationen, um zu antworten. Die häufigste Instanz von "Zero Padding" ist wahrscheinlich das Voranstellen von Nullen vor Datumsangaben: 01.05.2008> 01.05.2008. Meinst Du das?
Triptychon
6
Verwenden npm install sprintf-jsund fordern Sie Knoten-Apps in der sprintf('%0d6', 5);
gewünschten
function padWithZeroes(n, width) { while(n.length<width) n = '0' + n; return n;} ... vorausgesetzt nnicht negativ
Paolo
@Paolo diese Funktion funktioniert nicht, wenn n numerisch ist. Sie müssten n vor dem whilein einen String konvertieren, um darauf zugreifen zu könnenn.length
Nick F
1
Ein Liner ohne Math oder While-Schleifen oder Bibliotheken? mynum = "0".repeat((n=6-mynum.toString().length)>0?n:0)+mynum;
Adam Whateverson

Antworten:

226

Hinweis für die Leser!

Wie Kommentatoren hervorgehoben haben, ist diese Lösung "clever", und wie clevere Lösungen oft sind, ist sie speicherintensiv und relativ langsam. Wenn Ihnen die Leistung ein Anliegen ist, verwenden Sie diese Lösung nicht!

Möglicherweise veraltet : ECMAScript 2017 enthält String.prototype.padStart und Number.prototype.toLocaleString ist seit ECMAScript 3.1 vorhanden. Beispiel:

var n=-0.1;
n.toLocaleString('en', {minimumIntegerDigits:4,minimumFractionDigits:2,useGrouping:false})

... gibt "-0000.10" aus.

// or 
const padded = (.1+"").padStart(6,"0");
`-${padded}`

... gibt "-0000.1" aus.

Eine einfache Funktion ist alles was Sie brauchen

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
}

Sie können dies in eine Bibliothek backen, wenn Sie den Namespace oder was auch immer beibehalten möchten. Wie bei jQuery's Extend .

Peter Bailey
quelle
1
Jetzt müssen Sie sich nur noch um Zahlen wie 50.1234 kümmern und haben unten eine lesbare Version meiner Lösung! Ich ging jedoch davon aus, dass wir nur noch Polsterung hatten, nicht die gesamte Polsterung.
Coderjoe
7
Kein Fan davon, jedes Mal ein neues Array zu erstellen, wenn Sie einen Wert auffüllen möchten. Leser sollten sich der möglichen Auswirkungen auf den Speicher und die GC bewusst sein, wenn sie große Mengen davon ausführen (z. B. auf einem node.js-Server, der 1000 dieser Vorgänge pro Sekunde ausführt. Die Antwort von @ profitehlolz scheint die bessere Lösung zu sein .)
Broofa
6
Dies funktioniert nicht für negative Werte: zeroFill (-10, 7) -> "0000-10"
Digitalbad
2
Leistungsmaß unter drei Top-Antworten hier: jsperf.com/left-zero-pad
Tomsmeding
12
Ab ECMAScript 2017 gibt es eine integrierte Funktion padStart .
Tomas Nikodym
321

Einfacher Weg. Sie können eine Zeichenfolgenmultiplikation für das Pad hinzufügen und es in eine Funktion umwandeln.

var pad = "000000";
var n = '5';
var result = (pad+n).slice(-pad.length);

Als eine Funktion,

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
profitehlolz
quelle
95
Dies ist eine sehr schöne Lösung, die ich am besten gesehen habe. Aus Gründen der Übersichtlichkeit ist hier eine einfachere Version, mit der ich die Minuten in der Zeitformatierung auffülle: ('0' + Minuten) .slice (-2)
Luke Ehresman
17
Dies ist fünfmal langsamer als die Implementierung mit einer while-Schleife: gist.github.com/4382935
andrewrk
42
Dies hat eine FATAL FLAW mit größeren als erwarteten Zahlen - was sehr häufig vorkommt. Zum Beispiel paddy (888, 2)Ausbeuten 88und nicht 888wie erforderlich. Diese Antwort behandelt auch keine negativen Zahlen.
Brock Adams
8
@BrockAdams, Zerofill wird normalerweise für Fälle mit fester Breite und Formatierung verwendet. Daher denke ich, dass es weniger wahrscheinlich (oder sogar kein Problem) ist, wenn beim Versuch, eine 2-stellige Nullfüllung durchzuführen, eine dreistellige Zahl angegeben wird.
Seaux
1
("000000" + Somenum) Teilstr (-6,6) wobei die Anzahl der Nullen und die -6,6 der Padbreite entsprechen. Dieselbe Idee, aber Slice nehmen einen Parameter weniger; Ich bin mir nicht sicher, ob Slice schneller oder langsamer als Subtr ist. Natürlich benötigt meine Lösung keine Variablenzuweisung.
Slartibartfast
315

Ich kann all die komplexen Antworten hier nicht glauben ... Verwenden Sie einfach Folgendes:

var zerofilled = ('0000'+n).slice(-4);
Seaux
quelle
27
Gut bis auf negative Zahlen und Zahlen mit mehr als 4 Ziffern.
Wberry
12
@wberry Dies war kein produktionsbereiter Code, sondern eher eine einfache Erklärung der Grundlagen zur Lösung der vorliegenden Frage. Aka, es ist sehr einfach festzustellen, ob eine Zahl positiv oder negativ ist, und bei Bedarf das entsprechende Vorzeichen hinzuzufügen, also wollte ich mein einfaches Beispiel damit nicht zusammenfassen. Außerdem ist es genauso einfach, eine Funktion zu erstellen, die eine Ziffernlänge wie ein Argument verwendet und diese anstelle meiner fest codierten Werte verwendet.
Seaux
5
@Seaux, Sie sagten: " Ich kann nicht alle komplexen Antworten glauben" und erklärten sich dann die Komplexität, wenn Sie kommentiert wurden. Dies bedeutet, dass Sie verstehen, dass es Perspektiven gibt, aus denen Ihre Antwort nicht perfekt ist. Daher die Komplexität.
Om Shankar
2
@OmShankar mit "komplexen Antworten" bezog ich mich nicht auf erklärte oder detaillierte Antworten (die auf dieser Site offensichtlich empfohlen werden, obwohl meine Antwort nicht lautet), sondern auf Antworten, die unnötige Codekomplexität enthielten.
Seaux
7
Ich mag diese Antwort. In meinem speziellen Fall weiß ich, dass die Zahlen immer positiv sind und nie mehr als 3 Stellen haben. Dies ist häufig der Fall, wenn Sie mit führenden Nullen auffüllen und Ihre Eingabe bekannt ist. Nett!
Patrick Chu
110

Ich musste mir in letzter Zeit tatsächlich so etwas einfallen lassen. Ich dachte, es müsste einen Weg geben, dies ohne Schleifen zu tun.

Das habe ich mir ausgedacht.

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

Verwenden Sie es dann einfach und geben Sie eine Zahl für das Nullfeld an:

> zeroPad(50,4);
"0050"

Wenn die Zahl größer als die Auffüllung ist, wird die Zahl über die Auffüllung hinaus erweitert:

> zeroPad(51234, 3);
"51234"

Dezimalstellen sind auch in Ordnung!

> zeroPad(51.1234, 4);
"0051.1234"

Wenn es Ihnen nichts ausmacht, den globalen Namespace zu verschmutzen, können Sie ihn direkt zu Number hinzufügen:

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

Und wenn Sie lieber Dezimalstellen haben möchten, nehmen Sie Platz in der Polsterung ein:

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

Prost!



XDR hat eine logarithmische Variation entwickelt , die anscheinend eine bessere Leistung erbringt.

WARNUNG : Diese Funktion schlägt fehl, wenn num gleich Null ist (z. B. 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;
}

Apropos Leistung: Tomsmeding verglich die drei besten Antworten ( 4 mit der logarithmischen Variation ). Ratet mal, welches die beiden anderen deutlich übertroffen hat? :) :)

Coderjoe
quelle
9
Das ist gut, ich mag, wie es lesbar und robust ist. Das einzige, was ich ändern würde, ist der Name des numZerosParameters, da er irreführend ist. Es ist nicht die Anzahl der Nullen, die Sie hinzufügen möchten, sondern die Mindestlänge, die die Anzahl haben sollte. Ein besserer Name wäre numLengthoder sogar length.
Sinnvoll
13
+1. Im Gegensatz zu den höher bewerteten Antworten behandelt diese negative Zahlen und gibt beim Überlauf keine groben Fehler zurück !!?!
Brock Adams
10
Leistungsmaß unter drei Top-Antworten hier: jsperf.com/left-zero-pad
Tomsmeding
4
Ich habe die Leistung dieser Antwort durch die Verwendung von Logarithmen um über 100% verbessert. Bitte beachten Sie den logarithmischen Testfall unter http://jsperf.com/left-zero-pad/10
XDR
2
Die ursprüngliche Lösung ist besser, logarithmische Variation funktioniert nicht, wenn numsie Null sein kann ...
Ondra C.
69

Hier ist, was ich verwendet habe, um eine Zahl mit bis zu 7 Zeichen aufzufüllen.

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

Dieser Ansatz wird wahrscheinlich für die meisten Menschen ausreichen.

Bearbeiten: Wenn Sie es allgemeiner machen möchten, können Sie dies tun:

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

Bearbeiten 2: Beachten Sie, dass Sie seit ES2017 Folgendes verwenden können String.prototype.padStart:

number.toString().padStart(padding, "0")
Chetbox
quelle
Dies scheitert bei großen und negativen Zahlen. number = 123456789Zum Beispiel mit dem obigen Code.
Brock Adams
Diese Lösung ist für bestimmte Szenarien die bestmögliche! Ich habe keine Ahnung, warum wir uns das vorher nicht ausgedacht haben. Das Szenario ist: Sie haben eine Zahl, die immer positiv ist [wie Brock erwähnt hat], und Sie wissen, dass nicht mehr Zeichen als Ihr Limit benötigt werden. In unserem Fall haben wir eine Punktzahl, die wir in Amazon SDB speichern. Wie Sie wissen, kann SDB keine Zahlen vergleichen, daher müssen alle Ergebnisse mit Nullen aufgefüllt werden. Das ist extrem einfach und effektiv!
Krystian
4
Entschuldigung, ich hätte erwähnen sollen, dass dies bei negativen Zahlen nicht funktioniert. Ich denke, dies betrifft jedoch den häufigeren Fall positiver Zahlen. Zumindest macht es das, was ich brauche!
Chetbox
Benötigte dies wieder und erkannte, dass Sie nicht brauchen new String. Sie können einfach String-Literale verwenden.
Chetbox
3
(new Array(padding + 1).join("0")kann ersetzt werden durch"0".repeat(padding)
Pavel
34

Moderne Browser unterstützen jetzt padStart, Sie können jetzt einfach tun:

string.padStart(maxLength, "0");

Beispiel:

string = "14";
maxLength = 5; // maxLength is the max string length, not max # of fills
res = string.padStart(maxLength, "0");
console.log(res); // prints "00014"

Flimm
quelle
@Flimm zögern Sie nicht, das in der Antwort zu bearbeiten :) Es wurde vor 4 Jahren geschrieben, also bin ich sicher, dass sich die Dinge jetzt geändert haben
Sterling Archer
27

Leider gibt es viele unnötig komplizierte Vorschläge für dieses Problem, die normalerweise das Schreiben einer eigenen Funktion zur Durchführung von Mathematik- oder Zeichenfolgenmanipulationen oder das Aufrufen eines Dienstprogramms eines Drittanbieters umfassen. Es gibt jedoch eine Standardmethode in der Basis-JavaScript-Bibliothek mit nur einer Codezeile. Es kann sinnvoll sein, diese eine Codezeile in eine Funktion einzubinden, um zu vermeiden, dass Sie Parameter angeben müssen, die Sie niemals ändern möchten, wie z. B. den lokalen Namen oder Stil.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumIntegerDigits: 3,
    useGrouping: false
});

Dies erzeugt den Wert "005" für Text. Sie können auch die toLocaleString-Funktion von Number verwenden, um Nullen auf der rechten Seite des Dezimalpunkts aufzufüllen.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumFractionDigits: 2,
    useGrouping: false
});

Dies ergibt den Wert "5.00" für Text. Ändern Sie useGrouping in true, um Komma-Trennzeichen für Tausende zu verwenden.

Beachten Sie, dass die Verwendung toLocaleString()mit localesund optionsArgumenten in ECMA-402 separat standardisiert ist , nicht in ECMAScript. Ab heute implementieren einige Browser nur die grundlegende Unterstützung , dh toLocaleString()sie ignorieren möglicherweise alle Argumente.

Vollständiges Beispiel

Daniel Barbalace
quelle
Wow, das ist eine super saubere Lösung und funktioniert in node.js.
Jishi
Ich kicherte, als ich das Intro las - "unnötig komplizierte Vorschläge". Die Softwareentwicklung beinhaltet, wie in allen technischen Disziplinen, das Abwägen von Kompromissen. Ich habe diesen "Standardweg" selbst ausprobiert - und ihn zeitlich festgelegt. Es funktioniert definitiv, aber ich würde es niemals für sich wiederholende Anwendungen verwenden, da es im Vergleich zu vielen anderen "selbstgerollten" Lösungen so langsam ist.
Bearvarine
1
Zwar funktionieren viele integrierte JavaScript-Funktionen schlecht, wenn viele Daten durchlaufen werden, aber ich würde argumentieren, dass Sie dafür kein JavaScript verwenden sollten, auch nicht serverseitig wie Node.js. Wenn Sie viele Daten serverseitig verarbeiten müssen, sollten Sie eine bessere Plattform wie .NET oder Java verwenden. Wenn Sie clientseitige Daten für die Anzeige für den Endbenutzer verarbeiten, sollten Sie die Daten nur für das verarbeiten, was Sie gerade auf dem Bildschirm des Endbenutzers rendern. Rendern Sie beispielsweise nur die sichtbaren Zeilen einer Tabelle und verarbeiten Sie keine Daten für andere Straßen.
Daniel Barbalace
21

Wenn im Voraus bekannt ist, dass die Füllnummer einen bestimmten Wert nicht überschreitet, gibt es eine andere Möglichkeit, dies ohne Schleifen zu tun:

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

Testfälle hier: http://jsfiddle.net/jfriend00/N87mZ/

jfriend00
quelle
@BrockAdams - behoben für beide Fälle, die Sie erwähnen. Wenn die Zahl bereits so breit wie die Füllbreite ist, wird keine Füllung hinzugefügt.
jfriend00
Vielen Dank; +1. Die negativen Zahlen weichen jedoch geringfügig von der üblichen Konvention ab. In Ihrem Testfall -88sollte "-00088"zum Beispiel nachgeben .
Brock Adams
1
@BrockAdams - Ich war mir nicht sicher, ob ein Anruf zeroFill(-88, 5)produzieren sollte -00088oder -0088? Ich denke, es hängt davon ab, ob das widthArgument die gesamte Breite der Zahl oder nur die Anzahl der Ziffern (ohne das negative Vorzeichen) haben soll. Ein Implementierer kann das Verhalten einfach so ändern, dass das negative Vorzeichen nicht berücksichtigt wird, indem nur die --widthCodezeile entfernt wird.
jfriend00
19

Der schnelle und schmutzige Weg:

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

Für x = 5 und count = 6 haben Sie y = "000005"

Johann Philipp Strathausen
quelle
1
Ich habe y="0005"mit dem oben genannten bekommen, y = (new Array(count + 1 - x.toString().length)).join('0') + x;was mir gegeben haty="000005"
für
3
@ OrSiloni: Die kürzeste Codelösung ist tatsächlich('0000'+n).slice(-4)
Seaux
14

Hier ist eine kurze Funktion, die ich mir ausgedacht habe, um die Arbeit zu erledigen. Wenn jemand einen einfacheren Ansatz hat, können Sie ihn gerne teilen!

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

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

    return result;
}
Wilco
quelle
Ich denke nicht, dass es eine "einfachere" Lösung geben wird - es wird immer eine Funktion sein. Wir könnten eine Algorithmusdiskussion führen, aber am Ende des Tages erhalten Sie immer noch eine Funktion, die eine Zahl auf Null setzt.
Peter Bailey
Mein allgemeiner Rat ist, "for" -Schleifen zu verwenden, da diese in ECMAScript-Sprachen (ActionScript 1-3 und JavaScript) im Allgemeinen stabiler und schneller sind
cwallenpoole
Oder überspringen Sie die Iteration insgesamt;)
Peter Bailey
Einfachere Funktion? Wahrscheinlich nicht. Eine, die keine Schleife macht? Das ist möglich ... obwohl der Algorithmus nicht ganz trivial ist.
Coderjoe
1
Wow, so ziemlich alle obigen Kommentare sind falsch. Die Lösung von @ profitehlolz ist einfacher und für das Inlining geeignet (muss keine Funktion sein). Inzwischen for.vs. whileLeistung ist nicht unterschiedlich genug, um interessant zu sein: jsperf.com/fors-vs-while/34
broofa
12

Spät zur Party hier, aber ich benutze dieses Konstrukt oft, um Ad-hoc-Auffüllungen mit einem Wert ndurchzuführen, der als positive Dezimalzahl bekannt ist:

(offset + n + '').substr(1);

Wo offsetist 10 ^^ Ziffern.

ZB Auffüllen auf 5 Stellen, wobei n = 123:

(1e5 + 123 + '').substr(1); // => 00123

Die hexadezimale Version davon ist etwas ausführlicher:

(0x100000 + 0x123).toString(16).substr(1); // => 00123

Anmerkung 1: Ich mag auch die Lösung von @ profitehlolz, bei der es sich um die String-Version handelt, bei der die raffinierte Negativindex-Funktion von Slice () verwendet wird.

Broofa
quelle
12

Ich weiß wirklich nicht warum, aber niemand hat es auf die offensichtlichste Weise getan. Hier ist meine Implementierung.

Funktion:

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

Prototyp:

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

Sehr einfach, ich kann nicht sehen, wie dies einfacher sein kann. Aus irgendeinem Grund habe ich hier auf SO oft den Eindruck, dass die Leute nur versuchen, "for" - und "while" -Schleifen um jeden Preis zu vermeiden. Die Verwendung von Regex kostet wahrscheinlich viel mehr Zyklen für eine so triviale 8-stellige Auffüllung.

Vitim.us
quelle
11

Ich benutze dieses Snipet, um eine 5-stellige Darstellung zu erhalten

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

Die Kraft der Mathematik!

x = Ganzzahl zum Auffüllen
y = Anzahl der Nullen zum Auffüllen

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

Ich habe niemanden darauf hinweisen sehen, dass wenn Sie String.prototype.substr () mit einer negativen Zahl verwenden, dies von rechts zählt.

Eine einzeilige Lösung für die Frage des OP, eine 6-stellige nullgefüllte Darstellung der Zahl 5, lautet:

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

Verallgemeinernd werden wir bekommen:

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

Stephen Quan
quelle
8

Nach einer langen, langen Zeit des Testens von 15 verschiedenen Funktionen / Methoden, die in diesen Fragen gefunden wurden, weiß ich jetzt, welche die besten (die vielseitigsten und schnellsten) sind.

Ich habe 15 Funktionen / Methoden aus den Antworten auf diese Frage genommen und ein Skript erstellt, um die Zeit zu messen, die für die Ausführung von 100 Pads benötigt wird. Jedes Pad würde die Zahl 9mit 2000Nullen auffüllen. Dies mag übertrieben erscheinen, ist es aber, aber es gibt Ihnen eine gute Vorstellung von der Skalierung der Funktionen.

Den von mir verwendeten Code finden Sie hier: https://gist.github.com/NextToNothing/6325915

Sie können den Code jederzeit selbst ändern und testen.

Um die vielseitigste Methode zu erhalten, müssen Sie eine Schleife verwenden. Dies liegt daran, dass bei sehr großen Zahlen andere wahrscheinlich scheitern, während dies erfolgreich sein wird.

Also, welche Schleife soll verwendet werden? Nun, das wäre eine whileSchleife. Eine forSchleife ist immer noch schnell, aber eine whileSchleife ist nur etwas schneller (ein paar ms) - und sauberer.

Antworten wie die von Wilco, Aleksandar Toplekoder Vitim.usden Job perfekt machen.

Persönlich habe ich einen anderen Ansatz versucht. Ich habe versucht, eine rekursive Funktion zu verwenden, um die Zeichenfolge / Nummer aufzufüllen. Es funktionierte besser als Methoden, die einem Array beitreten, funktionierte aber immer noch nicht so schnell wie eine for-Schleife.

Meine Funktion ist:

function pad(str, max, padder) {
  padder = typeof padder === "undefined" ? "0" : padder;
  return str.toString().length < max ? pad(padder.toString() + str, max, padder) : str;
}

Sie können meine Funktion mit oder ohne Einstellung der Füllvariablen verwenden. Also so:

pad(1, 3); // Returns '001'
// - Or -
pad(1, 3, "x"); // Returns 'xx1'

Persönlich würde ich nach meinen Tests eine Methode mit einer while-Schleife verwenden, wie Aleksandar Toplekoder Vitim.us. Ich würde es jedoch leicht ändern, damit Sie die Füllzeichenfolge festlegen können.

Also würde ich diesen Code verwenden:

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'

Sie können es auch als Prototypfunktion verwenden, indem Sie diesen Code verwenden:

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'
Jack B.
quelle
Ich habe dies in eine jsfiddle eingefügt, damit andere es schnell testen können, und Ihre Version des Codes hinzugefügt : jsfiddle.net/kevinmicke/vnvghw7y/2 Ihre Version ist immer sehr wettbewerbsfähig und manchmal die schnellste. Vielen Dank für die ziemlich ausführlichen Tests.
Kevinmicke
8

Der erste Parameter ist eine beliebige reelle Zahl, der zweite Parameter ist eine positive Ganzzahl, die die minimale Anzahl von Stellen links vom Dezimalpunkt angibt, und der dritte Parameter ist eine optionale positive Ganzzahl, die die Zahl angibt, wenn die Ziffern rechts vom Dezimalpunkt stehen.

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
}

damit

           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'
Jack Allan
quelle
8

Dies ist die ES6-Lösung.

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

Lewis
quelle
Offensichtlich die eleganteste Lösung, die ich nur modifizieren würde, um 2 String-Konvertierungen zu vermeiden: const numStr = String(num)undreturn '0'.repeat(len - numStr.length) + numStr;
ngryman
8

In allen modernen Browsern können Sie verwenden

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

Hier ist die MDN-Referenz https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

Lifehack
quelle
5

Nicht, dass diese Frage mehr Antworten benötigt, aber ich dachte, ich würde die einfache lodash-Version hinzufügen.

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

Kunst
quelle
1
Besser:var zfill = _.partialRight(_.padStart, '0');
Droogans
3
Einige Leute werden wahrscheinlich protestieren "Ich möchte kein lodash verwenden", aber es ist kaum noch ein gültiges Argument, da Sie nur diese Funktion installieren können : npm install --save lodash.padleft, dann import padLeft from 'lodash.padleft'und lassen Sie das_.
Andy
5

Der neueste Weg, dies zu tun, ist viel einfacher:

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

output: "02"

MrE
quelle
(8).toLocaleString(undefined, {minimumIntegerDigits: 5})kehrt "00.008"für mich zurück, basierend auf meinem Gebietsschema.
le_m
5

Nur eine andere Lösung, aber ich denke, es ist besser lesbar.

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

Arthur
quelle
Gleich wie welcher andere?
Fabio sagt Reinstate Monica
4

Dieser ist weniger einheimisch, kann aber der schnellste sein ...

zeroPad = function (num, count) {
    var pad = (num + '').length - count;
    while(--pad > -1) {
        num = '0' + num;
    }
    return num;
};
Jonathan Neal
quelle
Ich denke du willst es tun pad = count - (num + '').length. negative Zahlen werden nicht gut behandelt, aber ansonsten ist es nicht schlecht. +1
Nickf
3

Meine Lösung

Number.prototype.PadLeft = function (length, digit) {
    var str = '' + this;
    while (str.length < length) {
        str = (digit || '0') + str;
    }
    return str;
};

Verwendungszweck

var a = 567.25;
a.PadLeft(10); // 0000567.25

var b = 567.25;
b.PadLeft(20, '2'); // 22222222222222567.25
Aleksandar Toplek
quelle
3

Warum nicht Rekursion verwenden?

function padZero(s, n) {
    s = s.toString(); // in case someone passes a number
    return s.length >= n ? s : padZero('0' + s, n);
}
lex82
quelle
padZero (223, 3) schlägt mit '0223' fehl
Serginho
Nun, ich nahm an, dass diese Funktion mit einem String als erstem Parameter aufgerufen wird. Ich habe es jedoch behoben.
Lex82
2

Einige Monkeypatching funktioniert auch

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"
Rodrigo
quelle
1
-1 Monkeypatching des Top-Level-Namespaces in Javascript ist eine schlechte Praxis.
Jeremy Wall
2
Richtig für Objekt- und Array-Objekte, aber String ist nicht schlecht
Rodrigo
2
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

...usw.

Prost

Madbreaks
quelle
Ich denke, es sollte eher so aussehen: var s = String(toPad); return (s.length < length) ? new Array(length - s.length + 1).join('0') + s : s;Wenn Sie es reparieren, werde ich meine Abwahl entfernen.
Zeichnen
@drewish Danke, dass du das verstanden hast, ich stimme deiner Bearbeitung zu (mit Ausnahme des fest codierten 0Join-Zeichens :) - Antwort aktualisiert.
Madbreaks
Ich denke, es wäre besser, den String in einer temporären Variablen zu speichern. Ich habe hier ein Benchmarking durchgeführt: jsperf.com/padding-with-memoization Es gibt auch Benchmarks für die Verwendung des neuen in "new Array". Die Ergebnisse für new sind allgegenwärtig, aber Memiozation scheint der richtige Weg zu sein.
Zeichnen
2

Die einfachste und einfachste Lösung, die Sie finden werden.

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