Two part question.
Part 1 is easy, but I'm wondering what you think is the most elegant solution:
What would be the best procedure to use to convert input into cleanly formatted and WITH "normal" comma placement. The input could range from:
$8000
8200
8,000.50
And I want it to output simply: 8,000
Part 2, may be easy I just don't know the right operation. I want to round numbers so that: it is rounded based on the number of digits. So that there are TWO unrounded digits at all time.
45,643 should be 46,000
453 should be 450
59,023,920 should be 59,000,000
The following code should answer both parts of the question:
var input = "$820322310"; // String input
input = input.replace(/[^0-9\.]/g, ""); // remove all unnecessary characters
input = input.replace(/\.[0-9]+/, ""); // remove all after decimal (convert to integer)
if(parseInt(input[2]) >= 5) { // rounding to two decimal places
input[1] = input.slice(0, 1) + (parseInt(input[1]) + 1) + input.slice(2, input.length);
}
var count = 0;
for(var i = input.length-1; i >= 0; i--) {
if(i > 2) {
input = input.slice(0, i-1) + "0" + input.slice(i, input.length);
}
if(++count == 3 && i != 0) {
count = 0;
input = input.slice(0, i) + "," + input.slice(i, input.length);
}
}
See this at JSFiddle.
Related
Is it possible to only convert the letters after 4 numbers. With not converting the numbers also. I use charCodeAt to do this.
What I want to do is only converting letters and not the numbers. Below I also convert the numbers. I want to convert things after the first 4 characters, the letters are converted to ascii numbers.
function convertZipcodeToInteger(letters){
letters = letters;
for(var i = 0; i < letters.length; i++){
let number = letters.charCodeAt(i) % 65 + "";
if (number.length < 2)
{
number = "0" + number;
}
console.log(number);
}
} convertZipcodeToInteger('7711AD');
What I am doing right now with the code is putting 7711AD into the letters parameter. Putting them through an for loop, so it converts all the letters(and numbers) with charCodeAt. When the number.length is smaller then 2 it gets a 0 in front of it.
What I want to do is convert it to this: 77110003 this is with the converted letters. I don't want the numbers converted, because they don't need to change.
You could test if the value is a number and if not take the letter and convert it to a numerical value based 36 and pad it before returning.
function convertZipcodeToInteger(string) {
function pad2(s) { return ('00' + s.toString()).slice(-2); }
return string
.split('')
.map(function (c) {
return /\d/.test(c)
? c
: pad2(parseInt(c, 36) - 10);
})
.join('')
};
function convertZipcodeToLetter(string) {
return string.slice(0, 4) + string
.slice(4)
.split(/(?=(?:..)*$)/)
.map(function (s) { return (+s + 10).toString(36).toUpperCase(); })
.join('');
}
console.log(convertZipcodeToInteger('7711AD'));
console.log(convertZipcodeToLetter('77110003'));
Is it possible to only convert the letters after 4 numbers.
Simply start your for-loop from 4
for(var i = 4; i < letters.length; i++){ //notice var i = 4
Edit
Looks like you want to replace letters every time they occur, not necessarily after 4 numbers,
"7711AD".replace(/[a-z]/gi, function(match){ return ( "0" + match.charCodeAt( 0 ) % 65).slice( -2 ) });
Demo
"7711AD".replace(/[a-z]/gi, function(match) {
return ( "0" + match.charCodeAt(0) % 65).slice( -2 ); //ensuring that single digit is padded with 0
});
Your question is a bit hard to understand but this is what I think you are after:
it can also be done without the function with just regexp magic
first 4 charaters are numbers and should only have 0 added (eg 07)
then 2 letters which should be encoded from 0-26 and always be two charaters long
function convertZipcodeToInteger(letters){
for(var i = 0; i < letters.length; i++){
let number = letters[i];
if (i>3) { number = letters.charCodeAt(i) % 65 + ""; }
if (number.length < 2) {
number = "0" + number;
}
console.log(number);
}
} convertZipcodeToInteger('7711AD');
I have a form that will collect various data about properties. The user enters in values to select fields and onBlur, those values are formatted with comma's, dollar signs, and/or percentage signs.
I'm trying to create some real time calculations based on those inputs, but I'm having a hard time getting started on this. I have created a jfiddle page and have been playing around with ideas for the past few hours, but I just cannot seem to get the first calculation working.
I know I need to strip out any characters and have tried parseInt, parseFloat, replace, ect. Just nothing seems to work.
Thank you in advance.
function formatNumber(number, digits, decimalPlaces, withCommas)
{
number = number.toString();
var simpleNumber = '';
// Strips out the dollar sign and commas.
for (var i = 0; i < number.length; ++i)
{
if ("0123456789.".indexOf(number.charAt(i)) >= 0)
simpleNumber += number.charAt(i);
}
number = parseFloat(simpleNumber);
if (isNaN(number)) number = 0;
if (withCommas == null) withCommas = false;
if (digits == 0) digits = 1;
var integerPart = (decimalPlaces > 0 ? Math.floor(number) :
Math.round(number));
var string = "";
for (var i = 0; i < digits || integerPart > 0; ++i)
{
// Insert a comma every three digits.
if (withCommas && string.match(/^\d\d\d/))
string = "," + string;
string = (integerPart % 10) + string;
integerPart = Math.floor(integerPart / 10);
}
if (decimalPlaces > 0)
{
number -= Math.floor(number);
number *= Math.pow(10, decimalPlaces);
string += "." + formatNumber(number, decimalPlaces, 0);
}
return string;
}
function sumCalc() { // function to remove comma and then calculate
var glasf =
document.getElementById('gross_land_sf').value.replace(/,/g, "");
document.getElementById('gross_land_acre').value = formatNumber(glasf/43560);
}
https://jsfiddle.net/vva3x3wu/4/
Is this what you want ? I did some fixes:
https://jsfiddle.net/vva3x3wu/11/
In the link you put in the comment you removed class .cal from the first input, so calculations will not star until you tab from the last input.
For an ObjectId in MongoDB, I work with a 24 digit hexadecimal number. Because I need to keep track of a second collection, I need to add 1 to this hexadecimal number.
In my case, here's my value
var value = "55a98f19b27585d81922ba0b"
What I'm looking for is
var newValue = "55a98f19b25785d81922ba0c"
I tried to create a function for this
function hexPlusOne(hex) {
var num = (("0x" + hex) / 1) + 1;
return num.toString(16);
}
This works with smaller hex numbers
hexPlusOne("eeefab")
=> "eeefac"
but it fails miserably for my hash
hexPlusOne(value)
=> "55a98f19b275840000000000"
Is there a better way to solve this?
This version will return a string as long as the input string, so the overflow is ignored in case the input is something like "ffffffff".
function hexIncrement(str) {
var hex = str.match(/[0-9a-f]/gi);
var digit = hex.length;
var carry = 1;
while (digit-- && carry) {
var dec = parseInt(hex[digit], 16) + carry;
carry = Math.floor(dec / 16);
dec %= 16;
hex[digit] = dec.toString(16);
}
return(hex.join(""));
}
document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("ffffffffffffffffffffffff"));
This version may return a string which is 1 character longer than the input string, because input like "ffffffff" carries over to become "100000000".
function hexIncrement(str) {
var hex = str.match(/[0-9a-f]/gi);
var digit = hex.length;
var carry = 1;
while (digit-- && carry) {
var dec = parseInt(hex[digit], 16) + carry;
carry = Math.floor(dec / 16);
dec %= 16;
hex[digit] = dec.toString(16);
}
if (carry) hex.unshift("1");
return(hex.join(""));
}
document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("ffffffffffffffffffffffff"));
I was curious te see whether user2864740's suggestion of working with 12-digit chunks would offer any advantage. To my surprise, even though the code looks more complicated, it's actually around twice as fast. But the first version runs 500,000 times per second too, so it's not like you're going to notice in the real world.
function hexIncrement(str) {
var result = "";
var carry = 1;
while (str.length && carry) {
var hex = str.slice(-12);
if (/^f*$/i.test(hex)) {
result = hex.replace(/f/gi, "0") + result;
carry = 1;
} else {
result = ("00000000000" + (parseInt(hex, 16) + carry).toString(16)).slice(-hex.length) + result;
carry = 0;
}
str = str.slice(0,-12);
}
return(str.toLowerCase() + (carry ? "1" : "") + result);
}
document.write(hexIncrement("55a98f19b27585d81922ba0b") + "<BR>");
document.write(hexIncrement("000000000000ffffffffffff") + "<BR>");
document.write(hexIncrement("0123456789abcdef000000000000ffffffffffff"));
The error comes from attempting to covert the entire 24-digit hex value to a number first because it won't fit in the range of integers JavaScript can represent distinctly2. In doing such a conversion to a JavaScript number some accuracy is lost.
However, it can be processed as multiple (eg. two) parts: do the math on the right part and then the left part, if needed due to overflow1. (It could also be processed one digit at a time with the entire addition done manually.)
Each chunk can be 12 hex digits in size, which makes it an easy split-in-half.
1 That is, if the final num for the right part is larger than 0xffffffffffff, simply carry over (adding) one to the left part. If there is no overflow then the left part remains untouched.
2 See What is JavaScript's highest integer value that a Number can go to without losing precision?
The range is 2^53, but the incoming value is 16^24 ~ (2^4)^24 ~ 2^(4*24) ~ 2^96; still a valid number, but outside the range of integers that can be distinctly represented.
Also, use parseInt(str, 16) instead of using "0x" + str in a numeric context to force the conversion, as it makes the intent arguably more clear.
I'm trying to show numbers in labels. If the number > 1000 the format should look like
1.000 or 1,000
I tried with toFixed but it is not the solution, also toPrecision but it gave me a number like 1,2e+
I tried with
number/1000
but when the number ends up with a 0, it disappears from the result, so how can i do this??
I whipped up the following function. It will add a comma after 3 digits. Works on whole numbers.
function formatNumber(num)
{
var formattedNumber = "";
var numString = num.toString();
var numCount = 0;
for (var index = numString.length - 1; index >= 0; index--)
{
if (numCount % 3 == 0
&& numString[index] != '-'
&& formattedNumber)
{
formattedNumber = ',' + formattedNumber;
}
formattedNumber = numString[index] + formattedNumber;
numCount++;
}
return formattedNumber;
}
You would have to write your own function. Something like this:
http://www.mredkj.com/javascript/nfbasic.html
EDIT: Found the original code
var number = 1310;
should be left alone.
var number = 120;
should be changed to "0120";
var number = 10;
should be changed to "0010";
var number = 7;
should be changed to "0007";
In all modern browsers you can use
numberStr.padStart(4, "0");
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
function zeroPad(num) {
return num.toString().padStart(4, "0");
}
var numbers = [1310, 120, 10, 7];
numbers.forEach(
function(num) {
var paddedNum = zeroPad(num);
console.log(paddedNum);
}
);
function pad_with_zeroes(number, length) {
var my_string = '' + number;
while (my_string.length < length) {
my_string = '0' + my_string;
}
return my_string;
}
try these:
('0000' + number).slice(-4);
or
(number+'').padStart(4,'0');
Here's another way. Comes from something I did that needs to be done thousands of times on a page load. It's pretty CPU efficient to hard code a string of zeroes one time, and chop as many as you need for the pad as many times as needed. I do really like the power of 10 method -- that's pretty flexible.
Anyway, this is as efficient as I could come up with:
For the original question, CHOOSE ONE of the cases...
var number = 1310;
var number = 120;
var number = 10;
var number = 7;
then
// only needs to happen once
var zeroString = "00000";
// one assignment gets the padded number
var paddedNum = zeroString.substring((number + "").length, 4) + bareNum;
//output
alert("The padded number string is: " + paddedNum);
Of course you still need to validate the input. Because this ONLY works reliably under the following conditions:
Number of zeroes in the zeroString is desired_length + 1
Number of digits in your starting number is less than or equal to your desired length
Backstory:
I have a case that needs a fixed length (14 digit) zero-padded number. I wanted to see how basic I could make this. It's run tens of thousands of times on a page load, so efficiency matters. It's not quite re-usable as-is, and it's a bit inelegant. Except that it is very very simple.
For desired n digits padded string, this method requires a string of (at least) n+1 zeroes. Index 0 is the first character in the string, which won't ever be used, so really, it could be anything.
Note also that string.substring() is different from string.substr()!
var bareNum = 42 + '';
var zeroString = "000000000000000";
var paddedNum = zeroString.substring(bareNumber.length, 14) + bareNum
This pulls zeroes from zeroString starting at the position matching the length of the string, and continues to get zeroes to the necessary length of 14. As long as that "14" in the third line is a lower integer than the number of characters in zeroString, it will work.
function pad(n, len) {
return (new Array(len + 1).join('0') + n).slice(-len);
}
might not work in old IE versions.
//to: 0 - to left, 1 - to right
String.prototype.pad = function(_char, len, to) {
if (!this || !_char || this.length >= len) {
return this;
}
to = to || 0;
var ret = this;
var max = (len - this.length)/_char.length + 1;
while (--max) {
ret = (to) ? ret + _char : _char + ret;
}
return ret;
};
Usage:
someString.pad(neededChars, neededLength)
Example:
'332'.pad('0', 6); //'000332'
'332'.pad('0', 6, 1); //'332000'
An approach I like is to add 10^N to the number, where N is the number of zeros you want. Treat the resultant number as a string and slice off the zeroth digit. Of course, you'll want to be careful if your input number might be larger than your pad length, but it's still much faster than the loop method:
// You want to pad four places:
>>> var N = Math.pow(10, 4)
>>> var number = 1310
>>> number < N ? ("" + (N + number)).slice(1) : "" + number
"1310"
>>> var number = 120
>>> number < N ? ("" + (N + number)).slice(1) : "" + number
"0120"
>>> var number = 10
>>> number < N ? ("" + (N + number)).slice(1) : "" + number
"0010"
…
etc. You can make this into a function easily enough:
/**
* Pad a number with leading zeros to "pad" places:
*
* #param number: The number to pad
* #param pad: The maximum number of leading zeros
*/
function padNumber(number, pad) {
var N = Math.pow(10, pad);
return number < N ? ("" + (N + number)).slice(1) : "" + number
}
I wrote a general function for this. It takes an input control and pad length as input.
function padLeft(input, padLength) {
var num = $("#" + input).val();
$("#" + input).val(('0'.repeat(padLength) + num).slice(-padLength));
}
With RegExp/JavaScript:
var number = 7;
number = ('0000'+number).match(/\d{4}$/);
console.log(number);
With Function/RegExp/JavaScript:
var number = 7;
function padFix(n) {
return ('0000'+n).match(/\d{4}$/);
}
console.log(padFix(number));
No loop, no functions
let n = "" + 100;
let x = ("0000000000" + n).substring(n.length);//add your amount of zeros
alert(x + "-" + x.length);
Nate as the best way I found, it's just way too long to read. So I provide you with 3 simples solutions.
1. So here's my simplification of Nate's answer.
//number = 42
"0000".substring(number.toString().length, 4) + number;
2. Here's a solution that make it more reusable by using a function that takes the number and the desired length in parameters.
function pad_with_zeroes(number, len) {
var zeroes = "0".repeat(len);
return zeroes.substring(number.toString().length, len) + number;
}
// Usage: pad_with_zeroes(42,4);
// Returns "0042"
3. Here's a third solution, extending the Number prototype.
Number.prototype.toStringMinLen = function(len) {
var zeroes = "0".repeat(len);
return zeroes.substring(self.toString().length, len) + self;
}
//Usage: tmp=42; tmp.toStringMinLen(4)
Use String.JS librairy function padLeft:
S('123').padLeft(5, '0').s --> 00123