Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #14625
| Message-ID | <1623778.oMNUckLgyt@PointedEars.de> (permalink) |
|---|---|
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
| Organization | PointedEars Software (PES) |
| Date | 2012-06-23 19:47 +0200 |
| Subject | Re: Placing 'zeros' in front of a number ? |
| Newsgroups | comp.lang.javascript |
| References | <a4ht2oFf7iU1@mid.individual.net> <68f86607-2127-46c8-b59d-a0b010335f32@googlegroups.com> <js1amg$mv1$1@dont-email.me> |
| Followup-To | comp.lang.javascript |
Followups directed to: comp.lang.javascript
Gregor Kofler wrote:
> Am 2012-06-22 05:18, Michael Haufe (TNO) meinte:
>> On Thursday, June 21, 2012 7:37:43 PM UTC-5, Mel Smith wrote:
>> [...]
>>> I've got a bunch of numbers (in string format), that I want to
>>> convert
>>> to strings of a standard length of four characters:
>>>
>>> e.g., '1' >>> '0001'
>>> '10' >>> '0010'
>>> '123' >>> '0123'
>>> '4567' >>> '4567' // leave as is for length of 4
>> [...]
>>
>> Perhaps something like this:
>>
>> String.prototype.padLeft = function(ch,len){
>> return Array(Math.max(0, len - this.length + 1)).join(ch) + this;
>> }
>
> Or
>
> String.prototype.lpad = function(len, fchar) {
> var i = len-this.length, pad = "", f = fchar || " ";
> while(i--) { pad += f; }
> return pad+this;
> };
>
> In a completely un-scientific benchmark in Firefox and Chromium this
> solution is about twice as fast (the difference becomes less with very
> long paddings). In any case I would change your order of arguments since
> "len" is in any case a required argument, whereas "ch" can be set to a
> default value.
Having reviewed these two solutions (see below), I still prefer mine (in
JSX:string.js@244):
/**
* Non-breaking space
*/
var CH_NBSP = "\xA0";
/**
* @param s : optional string
* Input string. If omitted and the calling object
* is a String object, it is used instead.
* @param n : optional number = 1
* Length of the resulting string. The default is 1,
* i.e. if the input string is empty, "0" is returned
* if c is <code>'0'</code>.
* @param c : optional string = CH_NBSP
* Character string to use for padding. The default
* is one non-breaking space.
* @param bRight : optional boolean = false
* If <code>true</code>, s is padded on the right,
* otherwise on the left.
* @param iStart : optional number
* Assume that s is iStart characters long.
* @return string
* The padded input string so that its length is n.
*/
var pad = jsx.string.pad = function(s, n, c, bRight, iStart) {
var constr;
if ((constr = this.constructor) && constr == String
&& typeof s != "string")
{
s = this;
}
if (!n)
{
n = 1;
}
if (!c)
{
c = CH_NBSP;
}
if (typeof s != "string")
{
s = String(s);
}
if (typeof iStart == "undefined")
{
iStart = s.length;
}
if (n <= iStart)
{
return s;
}
var a = [];
var missingLength = n - iStart + 1;
if (typeof a.join == "function"
&& (missingLength > -1) && (missingLength < Math.pow(2, 32)))
{
a.length = missingLength;
var rep = a.join(c);
if (bRight)
{
s += rep;
}
else
{
s = rep + s;
}
}
else
{
while (iStart < n)
{
if (bRight)
{
s += c;
}
else
{
s = c + s;
}
iStart++;
}
}
return s;
};
for which there is
/**
* @param s : optional string
* Input string. If omitted and the calling object
* is a String object, it is used instead.
* @param n : optional number
* Length of the resulting string. The default is 1,
* i.e. if the input string is empty, "0" is returned.
* @return string
* Input string with leading zeros so that
* its length is @{(n)}.
* @see
* #pad(string, number, string)
*/
function leadingZero(s, n)
{
var c;
if ((c = this.constructor) && c == String && typeof s != "string")
{
s = this;
}
return pad(s, n, "0");
}
here.
jsx.string.pad() being used by leadingZero() scores over the two solutions
above in several respects:
- It can be, but does not have to be, transferred to String instances or
String prototypes for use as a method (one might even consider using
`instanceof' now in case someone wants to inherit from String.prototype).
This makes it directly applicable to non-string values. Both solutions
above can only be used with objects inheriting from String.prototype.
- It does not pad if there is nothing to pad. Both solutions above do that.
- It has no dependency on the run-time values of `Array' and `Math.max',
so overwriting those properties should not be able to stop it from
working. Michael's solution depends on both.
- It minimizes method calls, which are expensive. Michael's solution uses
several method calls. Gregor's uses none, but at the price of repeated
non-native string concatenation when not necessary.
- It avoids repetitive non-native concatenation, which is expensive with
long strings. Michael's solution avoids that too, but at the price
of not being able to work with len > Math.pow(2, 32) - 1.
- It works efficiently with len smaller than or equal to
Math.pow(2, 32) - 1, but also works with greater values.
- It can handle awkward values. Gregor's solution hangs in an endless loop
when passed a len < this.length. Michael's handles that problem with
Math.max().
- It can handle literal 0 (any convertible false-value, really) as pad
value. Gregor's solution would default to a space character then.
- It pads with one *non-breaking* space by default. With Michael's
you have to be explicit, Gregor's defaults to a space.
- It is backwards-compatible to a large degree:
+ It uses a loop where is no Array.prototype.join() or the padding
length does not fit.
+ It does not depend on a single numeric argument to `Array' designating
the array length. This was a concern with earlier JavaScript versions –
but then again those versions also did not support the Array initializer
that I am using now. I am not aware of other implementations copying
the non-conforming behavior, although there may be some.
Michael's solution is not backwards-compatible. Gregor's is more
backwards-compatible than mine, but at the price of insufficient
fallbacks and reduced speed in the worst case.
- It can pad either left or right which makes it useful for an sprintf()
implementation. The solutions above require an extra implementation
for padding right-hand side.
- It is not depend on the string length of the value to be padded.
Apparently sometimes it is useful to let the string length of a value
appear longer or shorter than it actually is (I do not remember the
use-case right now, but I am sure there was one). You can pass a value
for iStart (don't ask) to tell jsx.string.pad() that the actual string
length does not matter.
Constructive comments and suggestions are welcome. (I know it still spoils
the global namespace a bit. This will be fixed but is kept until depending
code has been fixed.)
However: All our solutions fail to achieve properly left-padding string
representations of negative numbers. (Since fixing that would require yet
another parameter for jsx.string.pad() – to keep it general –, perhaps it is
time now to support a second `options' parameter; whenever it is not a
number, try accessing the properties of the referred object for options.)
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Placing 'zeros' in front of a number ? "Mel Smith" <med_cutout_syntel@aol.com> - 2012-06-21 18:37 -0600
Re: Placing 'zeros' in front of a number ? Gene Wirchenko <genew@ocis.net> - 2012-06-21 18:59 -0700
Re: Placing 'zeros' in front of a number ? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2012-06-21 20:18 -0700
Re: Placing 'zeros' in front of a number ? "Mel Smith" <med_cutout_syntel@aol.com> - 2012-06-21 22:51 -0600
Re: Placing 'zeros' in front of a number ? Gregor Kofler <usenet@gregorkofler.com> - 2012-06-22 10:34 +0200
Re: Placing 'zeros' in front of a number ? Scott Sauyet <scott.sauyet@gmail.com> - 2012-06-22 04:49 -0700
Re: Placing 'zeros' in front of a number ? "Mel Smith" <med_cutout_syntel@aol.com> - 2012-06-22 08:39 -0600
Re: Placing 'zeros' in front of a number ? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2012-06-22 13:05 -0700
Re: Placing 'zeros' in front of a number ? Gene Wirchenko <genew@ocis.net> - 2012-06-22 14:10 -0700
Re: Placing 'zeros' in front of a number ? "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2012-06-22 22:58 +0000
Re: Placing 'zeros' in front of a number ? Hans-Georg Michna <hans-georgNoEmailPlease@michna.com> - 2012-06-23 18:47 +0200
Re: Placing 'zeros' in front of a number ? "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2012-06-23 21:44 +0000
Re: Placing 'zeros' in front of a number ? "Mel Smith" <med_cutout_syntel@aol.com> - 2012-06-23 16:48 -0600
Re: Placing 'zeros' in front of a number ? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2012-06-23 16:56 -0700
Re: Placing 'zeros' in front of a number ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-06-23 19:47 +0200
Re: Placing 'zeros' in front of a number ? Gregor Kofler <usenet@gregorkofler.com> - 2012-06-23 20:52 +0200
Re: Placing 'zeros' in front of a number ? Gregor Kofler <usenet@gregorkofler.com> - 2012-06-23 21:01 +0200
Re: Placing 'zeros' in front of a number ? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2012-06-23 17:05 -0700
Re: Placing 'zeros' in front of a number ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-06-24 03:51 +0200
Re: Placing 'zeros' in front of a number ? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2012-06-25 20:19 -0700
Re: Placing 'zeros' in front of a number ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-06-26 09:04 +0200
Re: Placing 'zeros' in front of a number ? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2012-06-26 08:32 -0700
Re: Placing 'zeros' in front of a number ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-06-26 22:12 +0200
Re: Placing 'zeros' in front of a number ? "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2012-06-30 13:41 -0700
Re: Placing 'zeros' in front of a number ? Dr J R Stockton <reply1226@merlyn.demon.co.uk.not.invalid> - 2012-06-27 19:34 +0100
Re: Placing 'zeros' in front of a number ? Dr J R Stockton <reply1225@merlyn.demon.co.uk.not.invalid> - 2012-06-23 20:00 +0100
csiph-web