PDA

View Full Version : Replace charAt trouble



GfO
January 18th, 2008, 07:21 AM
Hi all!
I am getting a weird error that's about to drive me crazy.
The scenario is as follows:

I am reformatting a number to fit Norwegian standards. The number before formatting can be something like 1234.01, but needs to look like this: 1.234,00
The function I've written works for most numbers, but fails when there are two equal characters next to each other just where the thousand marker period is to be inserted.

That is;
12345.01 works and is converted to 12.345,00
while 22345.01 fails and is converted to 2.2345,00

Heres the code:


function numToString(str) {
var numToStr = new String(str);
//first we replace the "." with a ","
numToStr = numToStr.replace(".", ",");
//then we insert a thousand point marker (.)
if ((numToStr.charAt(numToStr.length - 7)!= "-")&&(numToStr.length > 6)) {
numToStr = numToStr.replace(numToStr.charAt(numToStr.length - 7), numToStr.charAt(numToStr.length - 7)+".");
}
//and then a hundred thousand point marker (.)
if ((numToStr.charAt(numToStr.length - 11)!= "-")&&(numToStr.length > 10)) {
numToStr = numToStr.replace(numToStr.charAt(numToStr.length - 11), numToStr.charAt(numToStr.length - 11)+".");
}
return numToStr;
}

trace(numToString(1111.45));

trace(numToString(1234.45));

trace(numToString(11111.45));

trace(numToString(1234.45));

trace(numToString(22620.33));

trace(numToString(12620.33));

trace(numToString(1234567.45));



Does anybody know what's going on?

neznein9
January 18th, 2008, 12:12 PM
Give this a try...


function numToString(n:Number):String{
// lets work with just the left half, ie. bigger than 0
// here's a # version, and a string to operate on
var wholeNum:uint = Math.floor(Math.abs(n));
var prefix:String = String(wholeNum);

// some vars to use in the loop
const dotsToAdd:int = Math.floor(prefix.length / 3);
const stringChunks:Array = [];

// split the string into 3-digit chunks
// note, we're going right to left
for(var i:int = 0; i < dotsToAdd; i++){
// break the last 3 digits into an array
stringChunks[i] = prefix.substr(-3, 3);

// take those numbers off the string
prefix = prefix.substring(0, prefix.length - 3);
}

// note that prefix now holds either an empty string
// or else 1 or 2 digits that the loop missed...

// loop back through and re-assemble
// this time left to right
for(var j:int = stringChunks.length - 1; j >= 0; j--){
// the 'if' makes sure you dont put a comma
// at the beginning of a # with 3/6/9 digits
if(prefix.length > 0) prefix += ',';
prefix += stringChunks[j];
}

// now the decimals
const freshString:String = String(n);
var suffix:String;

if(freshString.indexOf('.') > -1){
// the '2' at the end of this code, slices off all but 2 decimal places
// ie. .1234 becomes .12 - this does not handle rounding!!
suffix = '.' + freshString.substr(freshString.indexOf('.') + 1, 2);

// clean up numbers with only one decimal (.1 => .10)
if(suffix.length == 2) suffix = suffix + '0';
} else {
// handle cases where there is no decimal
suffix = '.00';
}

// and handle negatives
if(n < 0) prefix = '-' + prefix;

return prefix + suffix;
}

Felixz
January 18th, 2008, 12:30 PM
function numToString(string:String) {
var i:uint=0,array:Array=new Array();
var ending:String=string.slice(-6).replace(".",",");
string=string.slice(0,-6).split("").reverse().join("");
while(i * 3<string.length) array.push(string.slice(i*3,(1+i++)*3));
return array.join(".").split("").reverse().join("") + "." + ending;
}

GfO
January 20th, 2008, 05:09 AM
Thanks a lot guys!
neznein9, – your code works like a charm. Seems like you mixed up the use of "," and ".", but that was a minor issue to fix.

Felixz – your code fails on both small and large numbers so it didn't quite do it for me this time.

However, I am still curious why my original code fails, so if anyone is able to enlighten me, I would be most grateful!

Cheers!

Felixz
January 20th, 2008, 08:55 AM
Strange... it worked on big numbers having 12,13,14,15 chars... sorry for that... I was doing it fast and forgot abaout most important things
function numToString(num:Number) {
var string:String=String(num);
if (string.indexOf(".")==1) string+="0";
if (string.indexOf(".")==-1) string+=".00";
string=string.replace(".",",");
if (string.slice(0,-6)) {
var ending:String=string.slice(-6);
var i:uint=0,array:Array=new Array();
string=string.slice(0,-6).split("").reverse().join("");
while(i * 3<string.length) array.push(string.slice(i*3,(1+i++)*3));
string=array.join(".").split("").reverse().join("") + "." + ending;
}
return string;
}

neznein9
January 20th, 2008, 11:28 PM
numToStr = numToStr.replace(numToStr.charAt(numToStr.length - 7),numToStr.charAt(numToStr.length - 7)+".");

When you call replace(), you're targetting charAt(len - 7)...using your earlier example (22345.01) the seventh digit in is '2'...so you're telling replace() to look for '2'...replace() looks for the first instance of '2' from the left of the string so there's actually a lot of room for error in there (ie. any 2 before -7 would break it).