Làm thế nào tôi có thể đệm một giá trị với số không hàng đầu?


395

Cách được đề xuất để ghi lại giá trị trong JavaScript là gì? Tôi tưởng tượng rằng tôi có thể xây dựng một chức năng tùy chỉnh để chuyển các số không thành một giá trị được đánh máy, nhưng tôi tự hỏi liệu có cách nào trực tiếp hơn để làm điều này không?

Lưu ý: Theo "zerofiled", ý tôi là nó theo nghĩa cơ sở dữ liệu của từ này (trong đó biểu diễn zerofills 6 chữ số của số 5 sẽ là "000005").


Đây thực sự không đủ thông tin để trả lời. Ví dụ phổ biến nhất của "zero padding" có lẽ là trả trước các số 0 vào ngày: 5/1/2008> 05/01/2008. Đó có phải là ý bạn không?
Triptych

6
Đối với các ứng dụng nút, sử dụng npm install sprintf-jsvà yêu cầu nó trong tệp bạn cần:sprintf('%0d6', 5);
Dropogans

function padWithZeroes(n, width) { while(n.length<width) n = '0' + n; return n;} ... giả sử nkhông tiêu cực
Paolo

@Paolo hàm đó không hoạt động nếu n là số. Bạn cần chuyển đổi n thành Chuỗi trước khi whiletruy cậpn.length
Nick F

1
Một lớp lót không có vòng lặp Math hoặc While hoặc thư viện? mynum = "0".repeat((n=6-mynum.toString().length)>0?n:0)+mynum;
Adam Whateverson

Câu trả lời:


226

Lưu ý cho độc giả!

Như các nhà bình luận đã chỉ ra, giải pháp này là "thông minh", và như các giải pháp thông minh thường có, đó là bộ nhớ chuyên sâu và tương đối chậm. Nếu hiệu suất là mối quan tâm của bạn, đừng sử dụng giải pháp này!

Có khả năng lỗi thời : ECMAScript 2017 bao gồm String.prototype.padStart Number.prototype.toLocaleString có ở đó kể từ ECMAScript 3.1. Thí dụ:

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

... sẽ xuất ra "-0000.10".

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

... sẽ xuất ra "-0000.1".

Một chức năng đơn giản là tất cả những gì bạn cần

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
}

bạn có thể nướng cái này vào thư viện nếu bạn muốn bảo tồn không gian tên hoặc bất cứ thứ gì. Giống như với phần mở rộng của jQuery .


1
Bây giờ bạn chỉ cần chăm sóc các số như 50.1234 và bạn đã có phiên bản giải pháp dễ đọc của tôi bên dưới! Tôi đã làm, tuy nhiên, giả định rằng chúng tôi chỉ là đệm trái, không phải là đệm tổng thể.
coderjoe

7
Không phải là người thích tạo ra một mảng mới mỗi lần bạn muốn đệm một giá trị. Người đọc nên biết về tác động tiềm năng của bộ nhớ và GC nếu họ đang thực hiện những điều lớn này (ví dụ: trên máy chủ node.js đang thực hiện 1000 thao tác này mỗi giây. Câu trả lời của @ profitehlolz dường như là giải pháp tốt hơn .)
broofa

6
Đây không phải làm việc cho các giá trị tiêu cực: zeroFill (-10, 7) -> "0000-10"
digitalbath

2
Đo lường hiệu suất trong số ba câu trả lời hàng đầu tại đây: jsperf.com/left-zero-pad
tomsmeding

12
Kể từ ECMAScript 2017, có một chức năng padStart tích hợp .
Tomas Nikodym

321

Cách đơn giản. Bạn có thể thêm phép nhân chuỗi cho pad và biến nó thành một hàm.

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

Là một chức năng,

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
Đây là một giải pháp rất hay, tốt nhất tôi từng thấy. Để rõ ràng, đây là phiên bản đơn giản hơn mà tôi đang sử dụng để sắp xếp phút theo định dạng: ('0' + phút) .slice (-2)
Luke Ehresman


42
Điều này có một FLAW FATAL với số lượng lớn hơn số lượng dự kiến ​​- đó là một sự xuất hiện cực kỳ phổ biến. Ví dụ, paddy (888, 2)sản lượng 88và không 888theo yêu cầu. Câu trả lời này cũng không xử lý số âm.
Brock Adams

8
@BrockAdams, zerofill thường được sử dụng cho các trường hợp định dạng / số chiều rộng cố định - do đó tôi nghĩ rằng nó thực sự ít có khả năng (hoặc thậm chí là không có vấn đề) nếu được cung cấp số có 3 chữ số khi thử thực hiện zerofill 2 chữ số.
Seaux 8/12/13

1
("000000" + somenum) .substr (-6,6) trong đó số không và -6,6 tương ứng với chiều rộng của pad. Cùng một ý tưởng nhưng lát lấy một ít param; không chắc chắn nếu lát cắt nhanh hơn hoặc chậm hơn subtr. Tất nhiên giải pháp của tôi không cần gán biến.
slartibartfast

315

Tôi không thể tin tất cả các câu trả lời phức tạp ở đây ... Chỉ cần sử dụng điều này:

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

27
Tốt ngoại trừ số âm và số dài hơn 4 chữ số.
wberry

12
@wberry đây không phải là mã sẵn sàng sản xuất, mà là một lời giải thích đơn giản về những điều cơ bản để giải quyết câu hỏi trong tầm tay. Aka rất dễ dàng để xác định xem một số là dương hay âm và thêm dấu thích hợp nếu cần, vì vậy tôi không muốn gom ví dụ dễ dàng của mình với số đó. Ngoài ra, thật dễ dàng để tạo một hàm lấy độ dài chữ số như một đối số và sử dụng hàm đó thay vì các giá trị được mã hóa cứng của tôi.
Seaux

5
@Seaux, bạn nói: "không thể tin tất cả các câu trả lời phức tạp" , và sau đó bắt đầu tự giải thích sự phức tạp khi bình luận. Điều này có nghĩa là bạn hiểu rằng có những quan điểm mà từ đó câu trả lời của bạn không hoàn hảo. Do đó sự phức tạp.
Om Shankar

2
@OmShankar bởi "câu trả lời phức tạp", tôi không đề cập đến câu trả lời được giải thích hoặc chi tiết (điều này rõ ràng được khuyến khích trên trang web này mặc dù câu trả lời của tôi không), mà là câu trả lời có độ phức tạp mã không cần thiết.
Seaux

7
Tôi thích câu trả lời này. Trong trường hợp cụ thể của riêng tôi, tôi biết rằng các số luôn dương và không bao giờ quá 3 chữ số và đây thường là trường hợp khi bạn đệm với số 0 đứng đầu và đầu vào của bạn được biết đến. Đẹp!
Patrick Chu

110

Tôi thực sự đã phải đưa ra một cái gì đó như thế này gần đây. Tôi nghĩ rằng phải có một cách để làm điều đó mà không cần sử dụng các vòng lặp.

Đây là những gì tôi đã đưa ra.

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

Sau đó, chỉ cần sử dụng nó cung cấp một số đến không pad:

> zeroPad(50,4);
"0050"

Nếu số lớn hơn phần đệm, số sẽ mở rộng ra ngoài phần đệm:

> zeroPad(51234, 3);
"51234"

Số thập phân cũng tốt!

> zeroPad(51.1234, 4);
"0051.1234"

Nếu bạn không ngại làm ô nhiễm không gian tên toàn cầu, bạn có thể thêm trực tiếp vào Số:

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

Và nếu bạn muốn có số thập phân chiếm không gian trong phần đệm:

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

Chúc mừng!



XDR đã đưa ra một biến thể logarit dường như hoạt động tốt hơn.

CẢNH BÁO : Hàm này không thành công nếu num bằng 0 (ví dụ: 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;
}

Nói về hiệu suất, tomsmeding so sánh 3 câu trả lời hàng đầu ( 4 với biến thể nhật ký ). Đoán cái nào majorly vượt trội so với hai người kia? :)


9
Điều này là tốt, tôi thích cách nó dễ đọc và mạnh mẽ. Điều duy nhất tôi sẽ thay đổi là tên của numZerostham số, vì nó gây hiểu nhầm. Đây không phải là số không bạn muốn thêm, đó là số có độ dài tối thiểu. Một cái tên tốt hơn sẽ là numLengthhoặc thậm chí length.
Nhận thức

13
+1. Không giống như các câu trả lời được bình chọn cao hơn, câu trả lời này xử lý các số âm và không trả về các lỗi thô khi tràn !!?!
Brock Adams

10
Đo lường hiệu suất trong số ba câu trả lời hàng đầu tại đây: jsperf.com/left-zero-pad
tomsmeding

4
Tôi đã cải thiện hiệu suất của câu trả lời này hơn 100% bằng cách sử dụng logarit. Vui lòng xem trường hợp kiểm tra logarit tại http://jsperf.com/left-zero-pad/10
XDR

2
Giải pháp ban đầu tốt hơn, biến thể logarit không hoạt động nếu numcó thể bằng 0 ...
Ondra C.

69

Đây là những gì tôi đã sử dụng để đệm một số tối đa 7 ký tự.

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

Cách tiếp cận này có thể sẽ đủ cho hầu hết mọi người.

Chỉnh sửa: Nếu bạn muốn làm cho nó chung chung hơn, bạn có thể làm điều này:

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

Chỉnh sửa 2: Lưu ý rằng kể từ ES2017, bạn có thể sử dụng String.prototype.padStart:

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

Điều này thất bại, xấu, trên số lượng lớn và số âm. number = 123456789, với mã, ở trên, ví dụ.
Brock Adams

Giải pháp này là tốt nhất có thể cho các kịch bản xác nhận! Tôi không biết tại sao chúng tôi không nghĩ ra điều này trước đây. Kịch bản là: bạn đã có một số luôn dương [như Brock đã đề cập] và bạn biết rằng nó sẽ không lấy nhiều ký tự hơn giới hạn của bạn. Trong trường hợp của chúng tôi, chúng tôi có một số điểm mà chúng tôi lưu trữ trong Amazon SDB. Như bạn đã biết SDB không thể so sánh các con số, vì vậy tất cả các điểm phải được đệm bằng không. Điều này cực kỳ dễ dàng và hiệu quả!
Kstallian

4
Xin lỗi, tôi nên đề cập rằng điều này sẽ không hoạt động cho các số âm. Tôi nghĩ rằng điều này liên quan đến trường hợp số tích cực phổ biến hơn, mặc dù. Nó làm những gì tôi cần, ít nhất!
chetbox

Cần điều này một lần nữa và nhận ra bạn không cần new String. Bạn chỉ có thể sử dụng chuỗi ký tự.
chetbox

3
(new Array(padding + 1).join("0")có thể được thay thế bằng"0".repeat(padding)
Pavel

34

Các trình duyệt hiện đại hiện hỗ trợ padStart, giờ bạn có thể làm:

string.padStart(maxLength, "0");

Thí dụ:

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 cứ thoải mái chỉnh sửa câu trả lời :) Nó được viết 4 năm trước nên tôi chắc chắn mọi thứ đã thay đổi ngay bây giờ
Sterling Archer

27

Thật không may, có rất nhiều đề xuất phức tạp không cần thiết cho vấn đề này, thường liên quan đến việc viết hàm riêng của bạn để thực hiện thao tác toán học hoặc chuỗi hoặc gọi một tiện ích của bên thứ ba. Tuy nhiên, có một cách tiêu chuẩn để thực hiện việc này trong thư viện JavaScript cơ bản chỉ với một dòng mã. Có thể đáng để bọc một dòng mã này trong một hàm để tránh phải chỉ định các tham số mà bạn không bao giờ muốn thay đổi như tên hoặc kiểu cục bộ.

var amount = 5;

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

Điều này sẽ tạo ra giá trị "005" cho văn bản. Bạn cũng có thể sử dụng hàm toLocaleString của Number để đệm các số không ở bên phải dấu thập phân.

var amount = 5;

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

Điều này sẽ tạo ra giá trị "5,00" cho văn bản. Thay đổi useGrouping thành true để sử dụng dấu phẩy cho hàng nghìn.

Lưu ý rằng việc sử dụng toLocaleString()với localesoptionsđối số được tiêu chuẩn hóa riêng biệt trong ECMA-402 , không phải trong ECMAScript. Cho đến hôm nay, một số trình duyệt chỉ thực hiện hỗ trợ cơ bản , tức là toLocaleString()có thể bỏ qua mọi đối số.

Ví dụ hoàn chỉnh


Ồ, đây là một giải pháp siêu sạch và hoạt động trong node.js.
Jishi

Tôi cười thầm khi đọc phần giới thiệu - "những gợi ý phức tạp không cần thiết". Phát triển phần mềm, như trong tất cả các ngành kỹ thuật, liên quan đến việc cân nhắc sự đánh đổi. Tôi đã thử "cách tiêu chuẩn" này - và hẹn giờ. Nó chắc chắn hoạt động, nhưng tôi sẽ không bao giờ chọn sử dụng nó cho bất kỳ loại ứng dụng lặp đi lặp lại nào do nó chậm so với nhiều giải pháp "lăn tại nhà" khác.
bearvarine

1
Đúng, rất nhiều hàm JavaScript tích hợp hoạt động kém khi lặp qua nhiều dữ liệu, nhưng tôi cho rằng bạn không nên sử dụng JavaScript cho điều đó, ngay cả phía máy chủ như Node.js. Nếu bạn có nhiều dữ liệu để xử lý phía máy chủ, bạn nên sử dụng một nền tảng tốt hơn như .NET hoặc Java. Nếu bạn đang xử lý dữ liệu phía máy khách để hiển thị cho người dùng cuối, bạn chỉ nên xử lý dữ liệu cho những gì bạn hiện đang hiển thị cho màn hình của người dùng cuối. Ví dụ: chỉ hiển thị các hàng hiển thị của bảng và không xử lý dữ liệu cho các đường khác.
Daniel Barbalace

21

Nếu số điền được biết trước không vượt quá một giá trị nhất định, có một cách khác để làm điều này mà không có vòng lặp:

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

Các trường hợp thử nghiệm tại đây: http://jsfiddle.net/jfriend00/N87mZ/


@BrockAdams - Đã sửa cho cả hai trường hợp bạn đề cập. Nếu số đã rộng bằng chiều rộng điền, thì không có điền vào.
jfriend00

Cảm ơn; +1. Tuy nhiên, các số âm hơi khác so với quy ước thông thường. Trong trường hợp thử nghiệm của bạn, -88nên mang lại "-00088", ví dụ.
Brock Adams

1
@BrockAdams - Tôi không chắc liệu cuộc gọi zeroFill(-88, 5)có nên sản xuất -00088hay -0088không? Tôi đoán nó phụ thuộc vào việc bạn muốn widthđối số là toàn bộ chiều rộng của số hay chỉ là số chữ số (không bao gồm dấu âm). Người thực hiện có thể dễ dàng chuyển đổi hành vi để không bao gồm dấu âm bằng cách chỉ xóa --widthdòng mã.
bè00

19

Cách nhanh chóng và bẩn thỉu:

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

Với x = 5 và tính = 6 bạn sẽ có y = "000005"


1
Tôi đã nhận được y="0005"với những điều trên, y = (new Array(count + 1 - x.toString().length)).join('0') + x;là những gì đã cho tôiy="000005"
trước

3
@OrrSiloni: giải pháp mã ngắn nhất thực sự là('0000'+n).slice(-4)
Seaux

14

Đây là một chức năng nhanh chóng tôi đã đưa ra để thực hiện công việc. Nếu bất cứ ai có một cách tiếp cận đơn giản hơn, hãy chia sẻ!

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

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

    return result;
}

Tôi không nghĩ sẽ có một giải pháp "đơn giản hơn" - nó sẽ luôn là một chức năng nào đó. Chúng ta có thể có một cuộc thảo luận về thuật toán, nhưng vào cuối ngày, bạn vẫn sẽ kết thúc với một hàm tạo ra một số.
Peter Bailey

Lời khuyên chung của tôi là sử dụng các vòng lặp "cho" vì chúng thường ổn định hơn và nhanh hơn trong các ngôn ngữ ECMAScript (ActionScript 1-3 và JavaScript)
cwallenpoole

Hoặc, bỏ qua việc lặp lại hoàn toàn;)
Peter Bailey

Chức năng đơn giản hơn? Chắc là không. Một cái không lặp? Điều đó là có thể ... mặc dù thuật toán không hoàn toàn tầm thường.
coderjoe

1
Wow, khá nhiều tất cả các ý kiến ​​trên là không chính xác. Giải pháp của @ profitehlolz đơn giản hơn và phù hợp với nội tuyến (không cần phải là một hàm). Trong khi đó, for.vs. whilehiệu suất không đủ khác biệt để trở nên thú vị: jsperf.com/fors-vs- while 432
broofa

12

Đến bữa tiệc muộn ở đây, nhưng tôi thường sử dụng cấu trúc này để thực hiện phần đệm đặc biệt của một số giá trị n, được gọi là số thập phân dương:

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

Trong trường hợp offsetlà 10 ^^ chữ số.

Ví dụ: Đệm đến 5 chữ số, trong đó n = 123:

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

Phiên bản thập lục phân của điều này dài hơn một chút:

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

Lưu ý 1: Tôi cũng thích giải pháp của @ profitehlolz, đây là phiên bản chuỗi của điều này, sử dụng tính năng chỉ mục phủ định tiện lợi của lát ().


12

Tôi thực sự không biết tại sao, nhưng không ai làm điều đó theo cách rõ ràng nhất. Đây là cách thực hiện của tôi.

Chức năng:

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

Nguyên mẫu:

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

Rất đơn giản, tôi không thể thấy bất kỳ cách nào có thể đơn giản hơn. Vì một số lý do tôi dường như nhiều lần ở đây trên SO, mọi người chỉ cố gắng tránh các vòng lặp 'cho' và 'trong khi' bằng bất cứ giá nào. Sử dụng regex có thể sẽ tốn nhiều chu kỳ hơn cho phần đệm 8 chữ số tầm thường như vậy.


11

Tôi sử dụng snipet này để có được một đại diện gồm 5 chữ số

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


9

Sức mạnh của Toán học!

x = số nguyên cho pad
y = số lượng số 0 đến pad

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

9

Tôi không thấy ai chỉ ra thực tế rằng khi bạn sử dụng String.prototype.substr () với số âm, nó sẽ được tính từ bên phải.

Một giải pháp lót cho câu hỏi của OP, đại diện số 6 chữ số của số 5, là:

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

Tổng quát hóa chúng tôi sẽ nhận được:

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

Sau một thời gian dài, rất lâu để thử nghiệm 15 chức năng / phương pháp khác nhau được tìm thấy trong câu hỏi này, giờ đây tôi biết cái nào là tốt nhất (linh hoạt nhất và nhanh nhất).

Tôi đã lấy 15 hàm / phương thức từ các câu trả lời cho câu hỏi này và tạo một kịch bản để đo thời gian thực hiện 100 miếng đệm. Mỗi pad sẽ đệm số 9với2000 số không. Điều này có vẻ quá mức, và nó là, nhưng nó cung cấp cho bạn một ý tưởng tốt về quy mô của các chức năng.

Mã tôi đã sử dụng có thể được tìm thấy ở đây: https://gist.github.com/NextToNoth/6325915

Hãy tự sửa đổi và kiểm tra mã.

Để có được phương pháp linh hoạt nhất, bạn phải sử dụng một vòng lặp. Điều này là do với số lượng rất lớn những người khác có khả năng thất bại, trong khi đó, điều này sẽ thành công.

Vậy, sử dụng vòng lặp nào? Vâng, đó sẽ là một whilevòng lặp. Một forvòng lặp vẫn nhanh, nhưng một whilevòng lặp chỉ nhanh hơn một chút (vài ms) - và sạch hơn.

Câu trả lời như những người bằng Wilco, Aleksandar Toplekhoặc Vitim.ussẽ làm công việc hoàn hảo.

Cá nhân, tôi đã thử một cách tiếp cận khác. Tôi đã cố gắng sử dụng một hàm đệ quy để đệm chuỗi / số. Nó hoạt động tốt hơn các phương thức tham gia vào một mảng nhưng, vẫn không hoạt động nhanh như vòng lặp for.

Chức năng của tôi là:

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

Bạn có thể sử dụng chức năng của tôi có hoặc không có cài đặt biến đệm. Vì vậy, như thế này:

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

Cá nhân, sau khi thử nghiệm, tôi sẽ sử dụng một phương thức với vòng lặp while, như Aleksandar ToplekhoặcVitim.us . Tuy nhiên, tôi sẽ sửa đổi nó một chút để bạn có thể đặt chuỗi đệm.

Vì vậy, tôi sẽ sử dụng mã này:

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'

Bạn cũng có thể sử dụng nó như một chức năng nguyên mẫu, bằng cách sử dụng mã này:

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'

Tôi đặt cái này trong jsfiddle để giúp người khác kiểm tra nhanh, thêm phiên bản mã của bạn : jsfiddle.net/kevinmicke/vnvghw7y/2 Phiên bản của bạn luôn rất cạnh tranh và đôi khi là nhanh nhất. Cảm ơn các thử nghiệm khá đầy đủ.
kevinmicke

8

Tham số thứ nhất là bất kỳ số thực nào, tham số thứ hai là số nguyên dương chỉ định số chữ số tối thiểu ở bên trái dấu thập phân và tham số thứ ba là số nguyên dương tùy chọn chỉ định số nếu chữ số ở bên phải dấu thập phân.

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
}

vì thế

           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

Đây là giải pháp ES6.

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


Rõ ràng là giải pháp tao nhã nhất tôi chỉ cần sửa đổi nó để tránh chuyển đổi 2 chuỗi: const numStr = String(num)return '0'.repeat(len - numStr.length) + numStr;
ngryman

8

Trong tất cả các trình duyệt hiện đại, bạn có thể sử dụng

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

Dưới đây là tài liệu tham khảo MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart


5

Không phải là câu hỏi này cần nhiều câu trả lời hơn, nhưng tôi nghĩ rằng tôi sẽ thêm phiên bản lodash đơn giản này.

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


1
Tốt hơn:var zfill = _.partialRight(_.padStart, '0');
Dropogans 14/03/2016

3
Một số người có thể sẽ phản đối "Tôi không muốn sử dụng lodash" nhưng hầu như không còn là một đối số hợp lệ nữa vì bạn chỉ có thể cài đặt chức năng này : npm install --save lodash.padleft, sau đó import padLeft from 'lodash.padleft'và bỏ qua_.
Andy

5

Cách mới nhất để làm điều này đơn giản hơn nhiều:

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

output: "02"


(8).toLocaleString(undefined, {minimumIntegerDigits: 5})trả lại "00.008"cho tôi, dựa trên địa phương của tôi.
le_m


4

Cái này ít bản địa hơn, nhưng có thể là nhanh nhất ...

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

tôi nghĩ rằng bạn muốn làm pad = count - (num + '').length. số âm không được xử lý tốt, nhưng ngoài ra, nó không phải là xấu. +1
nickf

3

Giải pháp của tôi

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

Sử dụng

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

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

3

Tại sao không sử dụng đệ quy?

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) thất bại với '0223'
Serginho

Chà, tôi giả sử rằng hàm này được gọi với một chuỗi là tham số đầu tiên. Tuy nhiên, tôi đã sửa nó.
lex82

2

Một số khỉ cũng hoạt động

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 việc sắp xếp lại không gian tên toplevel trong javascript là thực tế tồi.
Jeremy Wall

2
Đúng cho các đối tượng Object và Array, nhưng String không tệ
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

...Vân vân.

Chúc mừng


Tôi nghĩ nó sẽ giống như: var s = String(toPad); return (s.length < length) ? new Array(length - s.length + 1).join('0') + s : s;nếu bạn sửa nó, tôi sẽ bỏ phiếu bầu của tôi xuống.
lôi cuốn

@drewish Cảm ơn bạn đã nắm bắt được điều đó, tôi đồng ý với chỉnh sửa của bạn (ngoại trừ phần cứng 0tham gia char char :) - Trả lời cập nhật.
Madbreaks

Tôi nghĩ sẽ tốt hơn nếu lưu trữ chuỗi thành một biến tạm thời. Tôi đã thực hiện một số điểm chuẩn về điều đó ở đây: jsperf.com/padding-with-memoization, nó cũng có điểm chuẩn cho việc sử dụng cái mới trong "Mảng mới", kết quả cho cái mới ở khắp mọi nơi nhưng việc ghi nhớ có vẻ như sẽ đi.
thu hút

2

Giải pháp đơn giản nhất , đơn giản nhất mà bạn sẽ tìm thấy.

function zerofill(number,length) {
    var output = number.toString();
    while(output.length < length) {
      output = '0' + output;
    }
    return output;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.