How can I modify the function below to make it stop adding commas once we hit the decimal marker?
addCommas = function(number) {
if(number === undefined) {
return '';
}
while(/(\d+)(\d{3})/.test(number.toString())) {
number = number.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
}
return number;
}
addCommas(0.123456); // Outputs 0.123,456, should output 0.123456
My method is to split the number into fractional and integer parts...
addCommas = function(number)
{
if (number === undefined)
return '';
var parts = number.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
}
document.write( addCommas(0.123456) + "<br />" );
document.write( addCommas(123456.123456) + "<br />" );
document.write( addCommas(123456) + "<br />" );
Just add ^[^.]* to the front of the pattern:
addCommas = function(number) {
if(number === undefined) {
return '';
}
while(/^[^.]*(\d+)(\d{3})/.test(number.toString())) {
number = number.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
}
return number;
}
You only have to do that for the .test() call.
I would break the string in two prior to using the regular expression. Such as:
RenanCommas = function(number) {
if(number === undefined) {
return '';
}
var parts = (number + "").split(".");
var integerPart = parts[0];
var decimalPart = parts.length > 1 ? parts[1] : "0";
while(/(\d+)(\d{3})/.test(integerPart.toString())) {
integerPart = integerPart.replace(/(\d+)(\d{3})/, '$1'+','+'$2');
}
return integerPart + "." + decimalPart;
}
Notice that you could also have decimalPart as an empty string. In that case, you could check whether or not it is empty before using it. If you use an empty string instead of "0", the last line would be something like:
return integerPart + (decimalPart ? ("." + decimalPart) : "");
And when you run it:
RenanCommas(12121241243.1123131232); // outputs "12,121,241,243.112312"
This seems to be working:
addCommas = function(number) {
return number.replace(/(\.\d+$)|(?!^)(?=(?:\d{3})+(?=\.|$))/g, function($0, $1) {
return ($1)?$1:','; });
}
Examples:
addCommas('0.123456');
"0.123456"
addCommas('987654.123456');
"987,654.123456"
addCommas('987654321');
"987,654,321"
Related
Following is my code, which is working fine in most scenarios except in case of leading Zeros. It should preserve trailing zeros like -001 + 1 = 002
Code -
function incrementString (str) {
if(str === '') return "1";
if(!str.slice(-1).match(/\d/)) return `${str}1`;
const replacer = x => {
// Check if number
return (parseInt(x) + 1).toString();
}
return str.replace(/\d+/g, replacer )
}
// Return foobar2 which is correct
console.log(incrementString("foobar1"))
// Return foobar100 which is correct
console.log(incrementString("foobar099"))
// Return foobar2 which is incorrect, is should be foobar002
console.log(incrementString("foobar001"))
// Return foobar1 which is incorrect, is should be foobar001
console.log(incrementString("foobar000"))
// Return foobar101 which is incorrect, is should be foobar0101
console.log(incrementString("foobar0100"))
You may use this regex soluton:
function incrementString (str) {
if(str === '') return "1";
if(!str.slice(-1).match(/\d/)) return `${str}1`;
const replacer = (m, g1, g2) => {
// Check if number
var nn = (g1?g1:"") + (parseInt(g2) + 1).toString()
return nn.slice(-1 * m.length)
}
return str.replace(/(0*)(\d+)/g, replacer )
}
// Return foobar2
console.log(incrementString("foobar1"))
// Return foobar100
console.log(incrementString("foobar099"))
// Return foobar002
console.log(incrementString("foobar001"))
// Return foobar001
console.log(incrementString("foobar000"))
// Return foobar0101
console.log(incrementString("foobar0100"))
// Return foobar01000
console.log(incrementString("foobar00999"))
// Return foobar010
console.log(incrementString("foobar009"))
Everything seems to be perfect, you need to only handle the regex part of the leading zeroes in your replacer function.Below is the updated code for the same.
function incrementString(str) {
if (str === '')
return "1";
if (!str.slice(-1).match(/\d/)) {
return `${str}1`;
}
const replacer = x => {
var leadingZerosMatched = x.match(/^0+/);
var incrementedNumber = (parseInt(x) + 1).toString();
var leadingZeroes;
if (leadingZerosMatched && incrementedNumber.length < x.length) {
leadingZeroes = leadingZerosMatched[0];
if(leadingZeroes.length === x.length) {
leadingZeroes = leadingZeroes.slice(0, leadingZeroes.length-1)
}
}
return leadingZeroes ? leadingZeroes + incrementedNumber : incrementedNumber;
}
return str.replace(/\d+/g, replacer)
}
You could split your string from digits and use padStart after increment to preserve leading 0:
const incrementString = (str) => {
const [chars, nums] = str.split(/(\d+)/)
return [
...chars,
String(Number(nums) + 1)
.padStart(nums.length, '0')
].join('')
}
console.log(incrementString("foobar1"))
console.log(incrementString("foobar099"))
console.log(incrementString("foobar001"))
console.log(incrementString("foobar000"))
console.log(incrementString("foobar0100"))
function incrementString (str) {
let [
openingPartial,
terminatingInt
] = str.split(/(\d*)$/);
if (terminatingInt) {
const incrementedInt = String(parseInt(terminatingInt, 10) + 1);
const leadingZeroCount = (terminatingInt.length - incrementedInt.length);
if (leadingZeroCount >= 1) {
terminatingInt = Array(leadingZeroCount).fill("0").concat(incrementedInt).join('');
} else {
terminatingInt = incrementedInt;
}
} else {
terminatingInt = '1';
}
return `${ (openingPartial || '') }${ terminatingInt }`;
}
// Should return 'foo_003_bar1'.
console.log(incrementString("foo_003_bar"));
// Should return 'foo_003_bar_01'.
console.log(incrementString("foo_003_bar_00"));
// Should return 'foobar1'.
console.log(incrementString("foobar"));
// Should return 'foobar2'.
console.log(incrementString("foobar1"));
// Should return 'foobar100'.
console.log(incrementString("foobar099"));
// Should return 'foobar002'.
console.log(incrementString("foobar001"));
// Should return 'foobar001'.
console.log(incrementString("foobar000"));
// Should return 'foobar0101'.
console.log(incrementString("foobar0100"));
.as-console-wrapper { max-height: 100%!important; top: 0; }
I have been trying to get the input to be considered as currency and have commas. I have the output showing currency with a decimal but it is missing the comma. I have tried to get these two things working together but I keep running into errors. Any help is appreciated!!
function calculate(){
var savingsVal = ($('#savingsVal').val());
var totalSavings = 0;
if (filterValues(savingsVal)) {
totalSavings = savingsVal * 0.15;
}
$('#totalSavings').val('$' + totalSavings);
}
function filterValues(eVal){
if (eVal.length == 0)
{
$('.errorMessage').text('Insert value');
$('.equipValCont').addClass('has-error');
return false;
}
else if(!$.isNumeric(eVal)){
$('.errorMessage').text('Please, enter only numbers');
$('.equipValCont').addClass('has-error');
return false;
} else{
$('.equipValCont').removeClass('has-error');
return true;
}
}
$('#calculator').submit(function(e){
e.preventDefault();
calculate();
});
With numeral.js this is as simple as:
var string = numeral(1000).format('0,0');
Not sure if you're opposed to using a library here, but numeral.js is wonderful.
For your validation, instead of checkingelse if(!$.isNumeric(eVal)){ use regex to validate your value. You must consider "," as a valid since your currency will allowed "," . below as sample
var currencyStr= "1,123.20";
if (/^\d{0,4}(\.\d{0,2})?$/.test(currencyStr))
alert("currency is valid");
you should change
if (/^\d{0,4}(\.\d{0,2})?$/.test(currencyStr))
alert("currency is valid");
to
if (/^(\d{0,3})(,\d{0,3})*(\.\d{0,2})?$/.test(currencyStr))
alert("currency is valid");
I hope this helps you
UPDATE
if you want add the correct commas to output, try something like this:
function formatStr( str ) {
str = str.replace( /,/g, "" );
var result = str.match( /^([^\.]+)(\.\d{0,2})?$/ ),
newStr = "",
integerStr = result[1] ? result[1] : "",
floatStr = result[2] ? result[2] : "",
j = 0;
for ( var i = integerStr.length - 1; i >= 0; i-- ) {
if ( j == 3 ) {
newStr = integerStr[i] + "," + newStr;
j = 1;
}
else {
newStr = integerStr[i] + newStr;
j++;
}
}
newStr = newStr + floatStr;
console.log( newStr );
return newStr;
}
formatStr( "12.34" );
formatStr( "123" );
formatStr( "1234.56" );
formatStr( "12345.6" );
I need to mangle (obfuscate) JavaScript strings using hexadecimal encoding.
Source code:
var a = 'a';
Mangled code:
var a = '\x61';
It is easy to convert string to a hexadecimal value:
var map = {
'\b': '\\b',
'\f': '\\f',
'\n': '\\n',
'\r': '\\r',
'\t': '\\t',
};
var hex = function (str) {
var result = '';
for (var i = 0, l = str.length; i < l; i++) {
var char = str[i];
if (map[char]) {
result += map[char];
} else if ('\\' == char) {
result += '\\' + str[++i];
} else {
result += '\\x' + str.charCodeAt(i).toString(16);
}
}
return result;
};
But when I add this string to the output file I get:
var a = '\\x61';
P.S. I use esprima/escodegen/estraverse to work with AST.
Below is an draft of implementation based on Качалов Тимофей's solution:
var esprima = require('esprima');
var estraverse = require('estraverse');
var escodegen = require('escodegen');
function stringToUnicode(string) {
return '"' + string.replace(/[\s\S]/g, function (escape) {
return '\\u' + ('0000' + escape.charCodeAt().toString(16)).slice(-4);
}) + '"';
}
var tree = esprima.parse(code);
//...
estraverse.replace(tree, {
leave: function(node){
if (node.type === 'Literal' && (node.raw[0] === '"' || node.raw[0] === '\'' )){
node['x-verbatim-property'] = {
content : stringToUnicode(node.value),
precedence: escodegen.Precedence.Primary
};
}
}
});
//...
var result = escodegen.generate(tree, {verbatim: 'x-verbatim-property'});
I am trying to make a function in javascript that would expand/split a string with dashes and show the process ( line by line ) using recursion.
for example, the string "anna" would become:
expand("anna") = expand("an")+"---"+expand("na") ->
"a"+"---"+"n"+"---"+"n"+"---"+"a"
and the desired output would be:
anna
an---na
a---n---n---a
I have achieved doing the following so far (I know it might not be the solution I am looking):
expand("anna") = an+"---"+expand("na")
= an+"---"+n+"---"+expand("a");
= an+"---"+n+"---+"a"
the output I am getting is:
an---n---a
I can't seem to concatenate the head though to do the first example.
My javascript function of expand is as follows:
function expand(word) {
if (word.length<=1) {
return word;
} else {
mid = word.length/2;
return word.substr(0,mid) + " " + expand(word.substr(mid,word.length));
}
}
document.write(expand("anna"));
I would need some tips to do this, otherwise (if it's the wrong stackexchange forum), please guide me where to post it.
this is my crazy attempt
var Word = function(str) {
this.isSplitable = function() {
return str.length > 1;
}
this.split = function() {
var p = Math.floor(str.length / 2);
return [
new Word(str.substr(0,p)),
new Word(str.substr(p,p+1))
];
}
this.toString = function() {
return str;
}
}
var expand = function(words) {
var nwords = [];
var do_recur = false;
words.forEach(function(word){
if(word.isSplitable()) {
var splitted = word.split();
nwords.push(splitted[0]);
nwords.push(splitted[1]);
do_recur = true;
}else{
nwords.push(word);
}
});
var result = [];
nwords.forEach(function(word){
result.push( word.toString() );
});
var result = result.join("--") + "<br/>";
if(do_recur) {
return result + expand(nwords);
}else{
return "";
}
}
document.write( expand([new Word("anna")]) );
This is what you need
expand = function(word) {
return [].map.call(word, function(x) {return x+'---'}).join('')
};
The joy of functional programming.
And with added code to deal with last character:
function expand(word) {
return [].map.call(word, function(x, idx) {
if (idx < word.length - 1)
return x+'---';
else return x
}).join('')
}
As I said that it is impossible to display the "process" steps of recursion while using recursion, here is a workaround that will output your desired steps:
var levels = [];
function expand(word, level) {
if (typeof level === 'undefined') {
level = 0;
}
if (!levels[level]) {
levels[level] = [];
}
levels[level].push(word);
if (word.length <= 1) {
return word;
} else {
var mid = Math.ceil(word.length/2);
return expand(word.substr(0, mid), level+1) + '---' + expand(word.substr(mid), level+1);
}
}
expand('anna');
for (var i = 0; i < levels.length; i++) {
console.log(levels[i].join('---'));
}
to see all steps the best that I whold do is:
function expand(word) {
if (word.length<=1) {
return word;
} else {
var mid = word.length/2;
var str1 = word.substr(0,mid);
var str2 = word.substr(mid,word.length);
document.write(str1 + "---" + str2 + "<br></br>");
return expand(str1) + "---" + expand(str2);
}
}
document.write(expand("anna"));
You have to return the two parts of the string:
function expand(word) {
output="";
if (word.length<=1) {
output+=word;
return output;
} else
{
var mid = word.length/2;
output+=word.substr(0,mid)+"---"+word.substr(mid)+" \n";//this line will show the steps.
output+=expand(word.substr(0,mid))+"---"+expand(word.substr(mid,word.length-1))+" \n";
return output;
}
}
console.log(expand("anna"));
Edit:
I added the output var and in every loop I concatenate the new output to it.
It should do the trick.
Hope the problem is in your first part. According to your algorithm, you are splitting your string anna in to two parts,
an & na
so you need to expand both parts until the part length is less than or equal to one. so your required function is the below one.
function expand(word) {
if (word.length<=1) {
return word;
} else {
mid = word.length/2;
return expand(word.substr(0,mid)) + " --- " + expand(word.substr(mid,word.length));
}
}
document.write(expand("anna"));
for instance I have this string:
013227004871996 300234060903250 013227003498171 013227003493834 300234010640390
013227003512963 300234061401690 013227004865956 013226009142122 013227008391574
300234061405690 013227003400573 300234061404700 013227003501479 013227003394495
013227004876284 300234061349230 013227004876284 013227004862011
and what I want to happen is that to separate the entry if it encounters 01322, so for instance in the example it will have array[0] = 013227004871996 300234060903250, array[1] = 013227003498171,
array[2] = 013227003493834
so basically I want to split it if the next entry starts with "013227".
This seems to work. Im matching everything that starts and is followed by 013227. Then I'm matching the last segment with .+
str.match(/013227.+?(?=013227)|.+/g)
Or even better:
str.split(/(?=013227)/)
var numbersStr = "013227004871996 300234060903250 013227003498171 013227003493834 300234010640390 013227003512963 300234061401690 013227004865956 013226009142122 013227008391574 300234061405690 013227003400573 300234061404700 013227003501479 013227003394495 013227004876284 300234061349230 013227004876284 013227004862011";
var pattern = new RegExp('01322[\\d]+');
var numbersArr = numbersStr.split(' ');
var numbersArrLength = numbersArr.length - 1;
for (var i = numbersArrLength; i >= 0; i--) {
if (!pattern.test(numbersArr[i])) {
numbersArr.splice(i, 1);
}
}
var separator = '01322';
"013227004871996 300234060903250 013227003498171 013227003493834 300234010640390"
.split(separator)
.filter(function(item){
return item;
}).map(function(item){
return separator + item;
})
var s = "013227004871996 300234060903250 013227003498171 013227003493834 300234010640390 "
+ "013227003512963 300234061401690 013227004865956 013226009142122 013227008391574 "
+ "300234061405690 013227003400573 300234061404700 013227003501479 013227003394495 "
+ "013227004876284 300234061349230 013227004876284 013227004862011";
var sp = s.split(" ");
var res = new Array();
var count=0;
sp.forEach(function(a) {
if(a.search("01322") === 0) {
if(res[count] === undefined) {
res[count] = a;
} else {
++count;
res[count] = a;
}
} else {
if(res[count] === undefined) {
res[count] = a;
} else {
res[count]+=" "+a;
}
}
});
console.log(res);
[ '013227004871996 300234060903250',
'013227003498171',
'013227003493834 300234010640390',
'013227003512963 300234061401690',
'013227004865956',
'013226009142122',
'013227008391574 300234061405690',
'013227003400573 300234061404700',
'013227003501479',
'013227003394495',
'013227004876284 300234061349230',
'013227004876284',
'013227004862011' ]
try this
function niceslice( string, delimiter ){
var result = string.split(delimiter);
for(var i = 1; i < result.length; i++){
result[i] = delimiter + result[i];
}
return result;
}
take note that this will not eliminate spaces in your example (but should be easily built in)
example usage
var str = 'anton albert andrew';
var output = niceslice( str, 'a' );
console.log( output ); // returns ['', 'anton ', 'albert ', 'andrew']
or in your case
var str = '013227004871996 300234060903250 013227003498171 013227003493834 300234010640390 013227003512963 300234061401690 013227004865956 013226009142122 013227008391574 300234061405690 013227003400573 300234061404700 013227003501479 013227003394495 013227004876284 300234061349230 013227004876284 013227004862011';
var output = niceslice( str, '013227' );