I was creating an associate array the other day. Riveting, I know.
I needed to sort this array by a piece of data, and I was lazy (like all healthy programmers), so I decided to prepend the data to a unique string and make that the key. Nailed, it sorts, right?
No. PHP doesn't realize that 1 is less than 12 when you're sorting strings. The solution I chose for sorting strings of numbers was to add leading zeros. The functions below can be used to do so.
PHP
function leading_zero($number, $num_digits) {
return str_repeat("0",($num_digits + -1 - floor(log10($number)))) . $number;
}
JavaScript
function leading_zero(number, num_digits) {
var zero = '0';
var nat_log = Math.floor(Math.log(number)/Math.log(10));
return zero.rep(num_digits - nat_log - 1) + '' + number;
}
function str_rep(n) {
var s = "", t = this.toString()
while (--n >= 0) s += t
return s
}
String.prototype.rep = str_rep
note: the javascript string repeating code courtesy of Web Refrence.
What's going on here
First I'm finding the base 10 log of $number. This can be done easily with PHP/JavaScriptlog ~10~ of $number
| $number | log 10 | PHP | Javascript |
|---|---|---|---|
| 1 | 0 | log10(1) | Math.log(1)/Math.log(10) |
| 10 | 1 | log10(10) | Math.log(10)/Math.log(10) |
| 16 | ~1.204 | log10(16) | Math.log(16)/Math.log(10) |
| 41 | ~1.613 | log10(41) | Math.log(41)/Math.log(10) |
| 125 | ~2.097 | log10(125) | Math.log(125)/Math.log(10) |
| 1337 | ~3.126 | log10(1337) | Math.log(1337)/Math.log(10) |
See the pattern yet? The log ~10~ of a number is about 1 less than the number of digits in the number.
Now I run the floor() function on the result of our log ~10~ to truncate the decimal and give us an easy-to-work-with integer.
floor() of log ~10~
| $number | log 10 | floor() |
|---|---|---|
| 1 | 0 | 0 |
| 10 | 1 | 1 |
| 16 | ~1.204 | 1 |
| 41 | ~1.613 | 1 |
| 125 | ~2.097 | 2 |
| 1337 | ~3.126 | 3 |
Nice. Now we can subtract our floor()'ed number from $num_digits, and then subtract an additional 1, and we have the resulting number of leading zeros to reach $num_digits (example: $num_digits = 4).
The art of subtraction
| $number | floor(log 10) | $num_digits | $num_digits – floor(log 10) – 1 |
|---|---|---|---|
| 1 | 0 | 4 | 3 |
| 10 | 1 | 4 | 2 |
| 16 | 1 | 4 | 2 |
| 41 | 1 | 4 | 2 |
| 125 | 2 | 4 | 1 |
| 1337 | 3 | 4 | 0 |
Having determined how many leading zeros we need, use a string repeating function (PHP: str_repeat(), Javascript: um, see the example above), and concatenate the string of zeros with your original number.
Update
My Twitter buddy ceejayoz has a PHP native solution for this:
@steyblind Psssst. $padded = str_pad($string, $length, '0', STR_PAD_LEFT);