Jak wstawić wartość wiodącymi zerami?


394

Jaki jest zalecany sposób zerowania wartości w JavaScript? Wyobrażam sobie, że mógłbym zbudować niestandardową funkcję, aby wstawiać zera do wartości zapisanej na maszynie, ale zastanawiam się, czy istnieje bardziej bezpośredni sposób na zrobienie tego?

Uwaga: Przez „zerowane” mam na myśli w znaczeniu tego słowa w bazie danych (gdzie 6-cyfrowa zerowa reprezentacja liczby 5 to „000005”).


To naprawdę za mało informacji, aby odpowiedzieć. Najczęstszym przypadkiem „wypełniania zerami” jest prawdopodobnie wstawianie zer na daty: 5/1/2008> 05/01/2008. Czy o to Ci chodziło?
Tryptyk

6
W przypadku aplikacji węzłowych użyj npm install sprintf-jsi wymagaj go w pliku, którego potrzebujesz:sprintf('%0d6', 5);
Droogans,

function padWithZeroes(n, width) { while(n.length<width) n = '0' + n; return n;} ... zakładając, że nnie jest negatywny
Paolo

@ Paolo ta funkcja nie działa, jeśli n jest liczbą. whileAby uzyskać dostęp , musisz przekonwertować n na String przedn.length
Nick F

1
Jeden linijka bez pętli matematycznych lub While? mynum = "0".repeat((n=6-mynum.toString().length)>0?n:0)+mynum;
Adam Whateverson,

Odpowiedzi:


225

Uwaga dla czytelników!

Jak zauważyli komentatorzy, to rozwiązanie jest „sprytne”, a ponieważ często sprytne są rozwiązania, zajmuje dużo pamięci i jest stosunkowo wolne. Jeśli zależy Ci na wydajności, nie używaj tego rozwiązania!

Potencjalnie przestarzały : ECMAScript 2017 zawiera String.prototype.padStart i Number.prototype.toLocaleString jest tam od ECMAScript 3.1. Przykład:

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

... wyświetli „-0000.10”.

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

... wyświetli „-0000.1”.

Wystarczy prosta funkcja

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
}

możesz upiec to w bibliotece, jeśli chcesz zachować przestrzeń nazw lub cokolwiek innego. Podobnie jak w przypadku rozszerzenia jQuery .


1
Teraz musisz tylko zadbać o liczby takie jak 50.1234, a poniżej masz czytelną wersję mojego rozwiązania! Założyłem jednak, że zostało nam tylko wypełnienie, a nie całkowite wypełnienie.
coderjoe

7
Nie jest fanem tworzenia nowej tablicy za każdym razem, gdy chcesz wstawić wartość. Czytelnicy powinni zdawać sobie sprawę z potencjalnego wpływu pamięci i GC, jeśli robią duże z nich (np. Na serwerze node.js, który wykonuje 1000 takich operacji na sekundę. Odpowiedź @ profitehlolz wydaje się lepszym rozwiązaniem .)
Broofa

6
Nie działa to dla wartości ujemnych: zeroFill (-10, 7) -> „0000-10”
digitalbath

2
Miara wydajności wśród trzech najlepszych odpowiedzi tutaj: jsperf.com/left-zero-pad
tomsmeding

12
Począwszy od ECMAScript 2017, jest wbudowana funkcja padStart .
Tomas Nikodym

321

Prosta droga. Możesz dodać mnożenie ciągów dla padu i przekształcić go w funkcję.

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

Jako funkcja,

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

95
To bardzo fajne rozwiązanie, najlepiej jakie widziałem. Dla jasności, oto prostszą wersję, której używam do wpisywania minut w formatowaniu czasu: („0” + minuty). Slice (-2)
Luke Ehresman

17
Jest to 5 razy wolniejsze niż implementacja z pętlą while: gist.github.com/4382935
andrewrk

42
Ma to WADA FATALNA o większej niż oczekiwano liczbie - co jest niezwykle częstym zjawiskiem. Na przykład paddy (888, 2)plony, 88a nie 888zgodnie z wymaganiami. Ta odpowiedź nie obsługuje również liczb ujemnych.
Brock Adams,

8
@BrockAdams, zerofill jest zwykle używany w przypadku liczb o stałej szerokości / przypadków formatowania - dlatego myślę, że w rzeczywistości byłoby mniej prawdopodobne (lub nawet nie występowało), gdyby podano 3-cyfrowy numer przy próbie wykonania 2-cyfrowego zerowania.
Seaux

1
(„000000” + somenum) .substr (-6,6) gdzie liczba zer i -6,6 odpowiada szerokości pola. Ten sam pomysł, ale plasterek zajmuje o jeden parametr mniej; nie jestem pewien, czy wycinek jest szybszy czy wolniejszy niż subtr. Oczywiście moje rozwiązanie nie wymaga przypisania zmiennej.
slartibartfast

315

Nie mogę uwierzyć we wszystkie złożone odpowiedzi tutaj ... Po prostu użyj tego:

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

27
Dobry, z wyjątkiem liczb ujemnych i liczb dłuższych niż 4 cyfry.
wberry

12
@wberry to nie miał być kod gotowy do produkcji, ale bardziej proste wyjaśnienie podstaw rozwiązywania danego pytania. Aka bardzo łatwo jest ustalić, czy liczba jest dodatnia czy ujemna, i w razie potrzeby dodać odpowiedni znak, więc nie chciałem w ten sposób zawrzeć mojego łatwego przykładu. Równie łatwo jest sprawić, by funkcja przyjmowała długość cyfry jako arg i używała jej zamiast moich wartości zapisanych na stałe.
Seaux

5
@Seaux powiedziałeś: „nie mogę uwierzyć we wszystkie złożone odpowiedzi” , a potem zacząłeś wyjaśniać sobie złożoność, kiedy skomentowałeś. Oznacza to, że rozumiesz, że istnieją perspektywy, z których Twoja odpowiedź nie jest doskonała. Stąd złożoność.
Om Shankar

2
@OmShankar przez „złożone odpowiedzi”, nie odnosiłem się do wyjaśnień lub szczegółowych odpowiedzi (które są oczywiście zachęcane na tej stronie, mimo że moja odpowiedź nie jest), ale raczej odpowiedzi, które zawierały niepotrzebną złożoność kodu.
Seaux,

7
Podoba mi się ta odpowiedź. W moim konkretnym przypadku wiem, że liczby są zawsze dodatnie i nigdy nie więcej niż 3 cyfry, i często dzieje się tak, gdy uzupełniasz wiodącymi zerami i twoje dane wejściowe są dobrze znane. Miły!
Patrick Chu

110

Ostatnio musiałem coś takiego wymyślić. Uznałem, że musi istnieć sposób, aby to zrobić bez użycia pętli.

Właśnie to wymyśliłem.

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

Następnie użyj go, podając klawisze numeryczne do zera:

> zeroPad(50,4);
"0050"

Jeśli liczba jest większa niż dopełnienie, liczba rozszerzy się poza dopełnienie:

> zeroPad(51234, 3);
"51234"

Dziesiętne też są w porządku!

> zeroPad(51.1234, 4);
"0051.1234"

Jeśli nie masz nic przeciwko zanieczyszczeniu globalnej przestrzeni nazw, możesz dodać ją bezpośrednio do 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;
}

A jeśli wolisz, aby ułamki dziesiętne zajmowały miejsce w wypełnieniu:

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

Twoje zdrowie!



XDR zaproponował wariację logarytmiczną, która wydaje się działać lepiej.

OSTRZEŻENIE : Ta funkcja nie działa, jeśli liczba równa się zero (np. Zeroopad (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;
}

Mówiąc o wydajności, tomsmeding porównał 3 najlepsze odpowiedzi ( 4 z odmianą dziennika ). Zgadnij, który z nich znacznie przewyższał pozostałe dwa? :)


9
To dobrze, podoba mi się to, jak jest czytelny i solidny. Jedyne, co chciałbym zmienić, to nazwa numZerosparametru, ponieważ wprowadza on w błąd. To nie jest liczba zer, które chcesz dodać, to minimalna długość, jaką powinna być liczba. Lepsza nazwa to numLengthlub nawet length.
Rozsądny

13
+1. W przeciwieństwie do wyżej głosowanych odpowiedzi, ta obsługuje liczby ujemne i nie zwraca rażących błędów przy przepełnieniu !!?!
Brock Adams,

10
Miara wydajności wśród trzech najlepszych odpowiedzi tutaj: jsperf.com/left-zero-pad
tomsmeding

4
Poprawiłem wydajność tej odpowiedzi o ponad 100%, używając logarytmów. Zobacz logarytmiczny przypadek testowy na stronie http://jsperf.com/left-zero-pad/10
XDR

2
Oryginalne rozwiązanie jest lepsze, wariacja logarytmiczna nie działa, jeśli nummoże wynosić zero ...
Ondra C.

69

Oto, czego użyłem do wpisania liczby do 7 znaków.

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

Takie podejście prawdopodobnie wystarczy dla większości ludzi.

Edycja: jeśli chcesz uczynić go bardziej ogólnym, możesz to zrobić:

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

Edycja 2: Zauważ, że od ES2017 możesz używać String.prototype.padStart:

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

Nie udaje się to w przypadku dużych liczb i liczb ujemnych. number = 123456789, na przykład z kodem powyżej.
Brock Adams,

To rozwiązanie jest najlepszym z możliwych dla scenariuszy certyfikatów! Nie mam pojęcia, dlaczego wcześniej tego nie wymyśliliśmy. Scenariusz jest taki: masz liczbę, która jest zawsze dodatnia [jak wspomniał Brock] i wiesz, że nie zajmie więcej znaków niż Twój limit. W naszym przypadku mamy wynik, który przechowujemy w Amazon SDB. Jak wiadomo SDB nie może porównywać liczb, więc wszystkie wyniki muszą być uzupełnione zerami. Jest to niezwykle łatwe i skuteczne!
Krystian

4
Przepraszam, powinienem wspomnieć, że to nie zadziała dla liczb ujemnych. Myślę jednak, że dotyczy to bardziej powszechnego przypadku liczb dodatnich. Przynajmniej robi to, czego potrzebuję!
chetbox

Potrzebowałem tego ponownie i zdałem sobie sprawę, że nie potrzebujesz new String. Możesz po prostu użyć literałów łańcuchowych.
chetbox

3
(new Array(padding + 1).join("0")można zastąpić"0".repeat(padding)
Pavel

34

Współczesne przeglądarki obsługują teraz padStart, możesz po prostu teraz:

string.padStart(maxLength, "0");

Przykład:

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 możesz edytować to w odpowiedzi :) Zostało napisane 4 lata temu, więc jestem pewien, że teraz wszystko się zmieniło
Sterling Archer

27

Niestety istnieje wiele niepotrzebnych, skomplikowanych sugestii dotyczących tego problemu, zwykle polegających na napisaniu własnej funkcji do wykonywania operacji matematycznych lub łańcuchowych lub wywołaniu narzędzia innej firmy. Istnieje jednak standardowy sposób na wykonanie tego w podstawowej bibliotece JavaScript za pomocą tylko jednego wiersza kodu. Warto zawinąć ten jeden wiersz kodu w funkcję, aby uniknąć konieczności określania parametrów, których nigdy nie chcesz zmieniać, takich jak lokalna nazwa lub styl.

var amount = 5;

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

Spowoduje to wygenerowanie wartości „005” dla tekstu. Możesz także użyć funkcji toLocaleString parametru Number, aby wstawić zera po prawej stronie przecinka dziesiętnego.

var amount = 5;

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

Spowoduje to wygenerowanie wartości „5,00” dla tekstu. Zmień useGrouping na true, aby używać separatorów przecinków dla tysięcy.

Należy pamiętać, że stosując toLocaleString()się localesi optionsargumentów jest znormalizowany oddzielnie w ECMA-402 , a nie w ECMAScript. Na dzień dzisiejszy niektóre przeglądarki implementują tylko podstawową obsługę , tzn. toLocaleString()Mogą ignorować wszelkie argumenty.

Kompletny przykład


Wow, to jest super czyste rozwiązanie i działa w node.js.
jishi

Zachichotałem, kiedy przeczytałem wstęp - „niepotrzebne skomplikowane sugestie”. Tworzenie oprogramowania, podobnie jak we wszystkich dyscyplinach inżynierskich, wiąże się z ważeniem kompromisów. Sam wypróbowałem ten „standardowy sposób” i sprawdziłem czas. To zdecydowanie działa, ale nigdy nie wybrałbym tego do powtarzalnych aplikacji ze względu na to, jak powolny jest w porównaniu do wielu innych rozwiązań „domowych”.
bearvarine

1
To prawda, że ​​wiele wbudowanych funkcji JavaScript działa słabo podczas zapętlania dużej ilości danych, ale argumentowałbym, że nie powinieneś używać do tego JavaScript, nawet po stronie serwera jak Node.js. Jeśli masz dużo danych do przetworzenia po stronie serwera, powinieneś użyć lepszej platformy, takiej jak .NET lub Java. Jeśli przetwarzasz dane po stronie klienta w celu wyświetlenia ich użytkownikowi końcowemu, powinieneś przetwarzać dane tylko dla tego, co obecnie renderujesz na ekranie użytkownika końcowego. Na przykład renderuj tylko widoczne wiersze tabeli i nie przetwarzaj danych dla innych dróg.
Daniel Barbalace

21

Jeśli z góry wiadomo, że liczba wypełnienia nie przekracza określonej wartości, istnieje inny sposób, aby to zrobić bez pętli:

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

Przypadki testowe tutaj: http://jsfiddle.net/jfriend00/N87mZ/


@BrockAdams - naprawiono dla obu wspomnianych przypadków. Jeśli liczba jest już tak szeroka jak szerokość wypełnienia, wówczas wypełnienie nie jest dodawane.
jfriend00

Dzięki; +1. Liczby ujemne są jednak nieco odbiegające od zwykłej konwencji. W twoim przypadku testowym -88powinien "-00088"na przykład ustąpić .
Brock Adams,

1
@BrockAdams - nie byłem pewien, czy dzwonienie zeroFill(-88, 5)powinno dać, -00088czy -0088? Myślę, że zależy to od tego, czy chcesz, aby widthargumentem była cała szerokość liczby, czy tylko liczba cyfr (nie licząc znaku ujemnego). Implementator może łatwo zmienić zachowanie, tak aby nie zawierało znaku ujemnego, po prostu usuwając --widthwiersz kodu.
jfriend00

19

Szybki i brudny sposób:

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

Dla x = 5 i count = 6 będziesz mieć y = "000005"


1
Dostałem y="0005"z powyższym, y = (new Array(count + 1 - x.toString().length)).join('0') + x;y="000005"
oto

3
@OrrSiloni: tak naprawdę najkrótszym rozwiązaniem jest kod('0000'+n).slice(-4)
Seaux

14

Oto szybka funkcja, którą wymyśliłem, aby wykonać tę pracę. Jeśli ktoś ma prostsze podejście, nie krępuj się nim podzielić!

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

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

    return result;
}

Nie sądzę, że będzie „prostsze” rozwiązanie - zawsze będzie to jakaś funkcja. Możemy dyskutować o algorytmach, ale pod koniec dnia nadal będziesz mieć funkcję zerującą liczbę.
Peter Bailey,

Moja ogólna rada to używanie pętli „for”, ponieważ są one na ogół bardziej stabilne i szybsze w językach ECMAScript (ActionScript 1-3 i JavaScript)
cwallenpoole,

Lub całkowicie pomiń iterację;)
Peter Bailey,

Prostsza funkcja? Prawdopodobnie nie. Taki, który się nie zapętla? Jest to możliwe ... chociaż algorytm nie jest całkowicie trywialny.
coderjoe

1
Wow, prawie wszystkie powyższe komentarze są niepoprawne. Rozwiązanie @ profitehlolz jest prostsze i nadaje się do wstawiania (nie musi być funkcją). Tymczasem for.vs. whilewydajność nie jest na tyle inna, aby była interesująca: jsperf.com/fors-vs-while/34
broofa 24.09.12

12

Późno na imprezę tutaj, ale często używam tego konstruktu do wypełniania ad-hoc pewnej wartości n, znanej jako dodatnia, dziesiętna:

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

Gdzie offsetjest 10 ^ ^ cyfr.

Np. Dopełnienie do 5 cyfr, gdzie n = 123:

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

Szesnastkowa wersja tego jest nieco bardziej szczegółowa:

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

Uwaga 1: Podoba mi się również rozwiązanie @ profitehlolz, które jest wersją łańcuchową, wykorzystując ciekawą funkcję indeksu ujemnego slice ().


12

Naprawdę nie wiem dlaczego, ale nikt nie zrobił tego w najbardziej oczywisty sposób. Oto moja implementacja.

Funkcjonować:

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

Bardzo prosto, nie widzę żadnego sposobu, w jaki może to być prostsze. Z jakiegoś powodu wydaje się, że wiele razy tutaj na SO, ludzie po prostu starają się za wszelką cenę unikać pętli „for” i „while”. Korzystanie z wyrażenia regularnego będzie prawdopodobnie kosztować znacznie więcej cykli w przypadku tak trywialnego 8-cyfrowego wypełnienia.


11

Używam tego fragmentu kodu, aby uzyskać reprezentację 5 cyfr

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


9

Moc matematyki!

x = liczba całkowita do wypełnienia
y = liczba zer do wypełnienia

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

9

Nie widziałem, żeby ktokolwiek zwrócił uwagę na fakt, że gdy używasz String.prototype.substr () z liczbą ujemną, to liczy się od prawej.

Jedno liniowe rozwiązanie pytania PO, 6-cyfrowa zerowa reprezentacja liczby 5, to:

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

Uogólniając otrzymamy:

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


8

Po długim, długim czasie testowania 15 różnych funkcji / metod znalezionych w odpowiedziach na pytania, teraz wiem, która jest najlepsza (najbardziej wszechstronna i najszybsza).

Z odpowiedzi na to pytanie wziąłem 15 funkcji / metod i stworzyłem skrypt do pomiaru czasu potrzebnego na wykonanie 100 padów. Każdy pad będzie pad numer 9z 2000zerami. Może się to wydawać przesadne i jest, ale daje dobre wyobrażenie o skalowaniu funkcji.

Kod, którego użyłem, można znaleźć tutaj: https://gist.github.com/NextToNothing/6325915

Możesz samodzielnie zmodyfikować i przetestować kod.

Aby uzyskać najbardziej uniwersalną metodę, musisz użyć pętli. Wynika to z faktu, że przy bardzo dużej liczbie inni mogą zawieść, a to się powiedzie.

Której pętli użyć? To byłaby whilepętla. forPętla nadal jest szybki, ale whilepętla jest tylko nieznacznie szybciej (kilka ms) - i czystsze.

Odpowiedzi takie jak te Wilco, Aleksandar Topleklub Vitim.uszrobią to doskonale.

Osobiście próbowałem innego podejścia. Próbowałem użyć funkcji rekurencyjnej do uzupełnienia ciągu / liczby. Działa lepiej niż metody łączące tablicę, ale nadal nie działa tak szybko jak pętla for.

Moja funkcja to:

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

Możesz użyć mojej funkcji z ustawieniem zmiennej dopełniania lub bez niej. Więc tak:

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

Osobiście po moich testach użyłbym metody z pętlą while, jak Aleksandar Topleklub Vitim.us. Jednak zmodyfikowałbym go nieco, abyś mógł ustawić łańcuch dopełniania.

Więc użyłbym tego kodu:

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'

Możesz również użyć go jako funkcji prototypowej, używając tego kodu:

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'

Umieszczam to w jsfiddle, aby inni mogli go szybko przetestować, dodając twoją wersję kodu: jsfiddle.net/kevinmicke/vnvghw7y/2 Twoja wersja jest zawsze bardzo konkurencyjna, a czasem najszybsza. Dzięki za dość wyczerpujące testy.
kevinmicke

8

Pierwszy parametr to dowolna liczba rzeczywista, drugi parametr jest liczbą całkowitą dodatnią określającą minimalną liczbę cyfr po lewej stronie przecinka dziesiętnego, a trzeci parametr jest opcjonalną liczbą całkowitą dodatnią określającą liczbę, jeśli cyfry znajdują się po prawej stronie przecinka dziesiętnego.

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
}

więc

           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'


8

To jest rozwiązanie ES6.

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


Najwyraźniej najbardziej eleganckie rozwiązanie, które po prostu zmodyfikowałbym, aby uniknąć konwersji 2 ciągów znaków: const numStr = String(num)ireturn '0'.repeat(len - numStr.length) + numStr;
ngryman

8

We wszystkich nowoczesnych przeglądarkach możesz używać

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

Oto odniesienie do MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart


5

Nie chodzi o to, że to pytanie wymaga więcej odpowiedzi, ale pomyślałem, że dodam jego prostą wersję.

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


1
Lepiej:var zfill = _.partialRight(_.padStart, '0');
Droogans

3
Niektórzy ludzie prawdopodobnie zaprotestują: „Nie chcę używać lodash”, ale to już nie jest poprawny argument, ponieważ możesz zainstalować tylko tę funkcję:, a npm install --save lodash.padleftnastępnie import padLeft from 'lodash.padleft'pomiń_.
Andy

5

Najnowszy sposób na zrobienie tego jest znacznie prostszy:

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

output: "02"


(8).toLocaleString(undefined, {minimumIntegerDigits: 5})zwraca "00.008"za mnie, w oparciu o moje ustawienia regionalne.
le_m


4

Ten jest mniej rodzimy, ale może być najszybszy ...

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

myślę, że chcesz to zrobić pad = count - (num + '').length. liczby ujemne nie są dobrze obsługiwane, ale poza tym nie jest źle. +1
nickf

3

Moje rozwiązanie

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

Stosowanie

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

var b = 567.25;
b.PadLeft(20, '2'); // 22222222222222567.25

3

Dlaczego nie skorzystać z rekurencji?

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

padZero (223, 3) kończy się niepowodzeniem z „0223”
Serginho,

Cóż, założyłem, że ta funkcja jest wywoływana z łańcuchem jako pierwszym parametrem. Jednak to naprawiłem.
lex82 18.10.16

2

Niektóre monkeypatching również działają

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"

1
-1 monkeypatching najwyższego poziomu przestrzeni nazw w javascript jest złą praktyką.
Jeremy Wall,

2
Prawda dla obiektów Object i Array, ale String nie jest zły
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

...itp.

Twoje zdrowie


Myślę, że powinno to być bardziej: var s = String(toPad); return (s.length < length) ? new Array(length - s.length + 1).join('0') + s : s;jeśli to naprawisz, usunę mój głos negatywny.
zwrócił

@drewish Dziękujemy za wyłapanie tego, zgadzam się z twoją edycją (z wyjątkiem zakodowanego 0dołączenia char :) - Odpowiedź zaktualizowana.
Madbreaks

Myślę, że lepiej byłoby przechowywać ciąg w zmiennej tymczasowej. Zrobiłem tutaj kilka testów porównawczych: jsperf.com/padding-withmemoization , ma również testy porównawcze użycia nowego w „nowej tablicy” wyniki dla nowych są wszędzie, ale memiozacja wydaje się być dobrą drogą.
zwrócił się

2

Najprostsze , najbardziej prosta rozwiązanie znajdziesz.

function zerofill(number,length) {
    var output = number.toString();
    while(output.length < length) {
      output = '0' + output;
    }
    return output;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.