SoFunction
Updated on 2025-04-10

Make numeric string complement 0 in js (js complement zero)

One of the common problems I encounter is the format of the date "1976-02-03 HH:mm:ss". My simplest way to deal with it is:

function formatDate(d) {
 var D=['00','01','02','03','04','05','06','07','08','09']
 with (d || new Date) return [
  [getFullYear(), D[getMonth()+1]||getMonth()+1, D[getDate()]||getDate()].join('-'),
  [D[getHours()]||getHours(), D[getMinutes()]||getMinutes(), D[getSeconds()]||getSeconds()].join(':')
 ].join(' ');
}

This method is relatively simple in logic and the rules are simple. Apart from using with(d||new Date), it is not a skill. However, if you use this method to make 0 of numeric strings, the result will obviously be bad. 51js's Moon Shadow provides another solution:

function pad(num, n) {
 return Array(n>num?(n-(''+num).length+1):0).join(0)+num;
}

The call example is as follows:

pad(100, 4); // Output:0100

Yueying analyzes the techniques here, as well as the balance between code length and efficiency:
The last Yueying recommends the "simple and eternal method":

/* Rustic and long-lasting method by lifesinger */
function pad(num, n) {
  var len = ().length;
  while(len < n) {
    num = "0" + num;
    len++;
  }
  return num;
}

This was analyzed in the blog of classmate "Cuming a Bird if You Are Nothing"
There is one thing that Yueying didn’t do, that is, she didn’t explain “Why is that short code less efficient?”.
The answer is "On the surface, it seems to be efficient to use instead of loops, but forget about the overhead of creating an array". Is there any way to do this? I have another solution. as follows:

/* Table lookup method (incomplete) by aimingoo */
pad = function(tbl) {
 return function(num, n) {
  return (((tbl[n = ().length]) || (tbl[n] = Array(n).join(0))) + num);
 }
}([]);

This method is the same as the formatDate() in the previous one, except that the table in formatDate() is a definite array, while the array here is dynamically generated and then cached in tbl[]. This cached tbl[] array is used in the form of a function call parameter, which is kept in the upper closure of the final pad() function. In order to make the above process clearer, I rearrange the code format as follows:

pad = function(tbl) {
 return function(num, n) {
  return (
   ((tbl[n = ().length]) ||
    (tbl[n] = Array(n).join(0))) +
   num
  );
 }
}([]);

OK At this point, don’t worry, there are two more problems to be solved. First, when there is no need to make up 0, the above tbl[0] returns a null value, so it will enter the second branch of the "||" operation, which causes Array() to recalculate once, which means that "the efficiency of not making up 0 is actually the lowest." Second, when the length of num is greater than n, it becomes "compensated with negative zeros". "Filling up negative zeros" obviously does not work, and it is generally treated as "no need to fill up zeros", so we return to the first question.

These two problems can be solved at once, but in fact they are more judgments:

/* Table lookup method (complete version) by aimingoo */
pad = function(tbl) {
 return function(num, n) {
  return (0 >= (n = ().length)) ? num : (tbl[n] || (tbl[n] = Array(n+1).join(0))) + num;
 }
}([]);

Of course, you can also sort out this code format as before. Or, use a version that does not use "sequential operations (functional languages)" at all:

/* Table lookup method (procedural version) by aimingoo */
pad = function() {
 var tbl = [];
 return function(num, n) {
  var len = ().length;
  if (len <= 0) return num;
  if (!tbl[len]) tbl[len] = (new Array(len+1)).join('0');
  return tbl[len] + num;
 }
}();

Algorithms are always like this. If it is either time to change space, or space to change time. The "simple and eternal method" of The Legend of the Condor Heroes is the method of changing time to space, and the table lookup method here is the plan of changing space to time. This function will continue to an array of strings in tbl. If num changes very often, then efficiency will not be greatly improved - for systems that change too frequently, cache is of little significance. In fact, the logic is almost the same, and Yueying just took one step away.