How do I increment a string with numbers? - javascript

I need to increment a value similar to this:
A001 becomes A002
A999 becomes B001
B001 becomes B002
etc
Z999 becomes A001
I can increment an integer like this:
var x = 5;
x++;
Yields x = 6
I can increment an character like this:
var str = 'A';
str = ((parseInt(str, 36)+1).toString(36)).replace(/0/g,'A').toUpperCase();
if (str =='1A') {
str = 'A';
}
Yields the next character in the alphabet.
This code seems to work, but I'm not sure it's the best way?
var str = 'Z999';
if (str == 'Z999') {
results = 'A001';
}
else {
var alpha = str.substring(0,1);
num = str.substring(1,4);
if (alpha != 'Z' && num == '999') {
alpha= ((parseInt(alpha, 36)+1).toString(36)).replace(/0/g,'A').toUpperCase();
}
num++;
var numstr = num + "";
while (numstr .length < 3) numstr = "0" + numstr ;
if (numstr == 1000) {
numstr = '001';
}
results = alpha + numstr;
}
results seems to give the correct answer. Yes?

You could use parseInt(input.match(/\d+$/), 10) to extract the number at the end of the string and input.match(/^[A-Za-z]/) to retreive the single character at the beginning.
Increment and pad the number accordingly, and increment the character if the number is over 999 by retrieving the character's character code and incrementing that.
String.fromCharCode(letter.charCodeAt(0) + 1);
Full code/example:
function incrementNumberInString(input) {
var number = parseInt(input.trim().match(/\d+$/), 10),
letter = input.trim().match(/^[A-Za-z]/)[0];
if (number >= 999) {
number = 1;
letter = String.fromCharCode(letter.charCodeAt(0) + 1);
letter = letter === '[' ? 'A': (letter === '{' ? 'a' : letter);
} else {
number++;
}
number = '000'.substring(0, '000'.length - number.toString().length) + number;
return letter + number.toString();
}
document.querySelector('pre').textContent =
'A001: ' + incrementNumberInString('A001')
+ '\nA999: ' + incrementNumberInString('A999')
+ '\nB001: ' + incrementNumberInString('B001')
+ '\nB044: ' + incrementNumberInString('B044')
+ '\nZ999: ' + incrementNumberInString('Z999');
<pre></pre>
Output:
A001: A002
A999: B001
B001: B002
B044: B045
D7777: E001

Try storing A-Z in an array , using String.prototype.replace() with RegExp /([A-Z])(\d+)/g to match uppercase characters , digit characters . Not certain what expected result is if "Z999" reached ?
var arr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
var spans = document.querySelectorAll("span");
function count(el) {
var data = el.innerHTML.replace(/([A-Z])(\d+)/g, function(match, text, n) {
var _text, _n;
if (Number(n) === 999) {
_text = arr[ arr.indexOf(text) + 1 ];
} else {
_text = text
};
// `"Z999"` condition ?
if (_text === undefined) {
return "<mark>" + text + n + "</mark>"
}
_n = Number(n) + 1 < 1000 ? Number(n) + 1 : "001";
if (n < 10) {
return _text + n.slice(0, 2) + _n
};
if (n < 100) {
return _text + n.slice(0, 1) + _n
} else {
return _text + _n
}
});
el.innerHTML = data
}
for (var i = 0; i < spans.length; i++) {
count(spans[i])
}
<span>A001</span>
<span>A999</span>
<span>B001</span>
<span>C999</span>
<span>D123</span>
<span>Z999</span>

Related

Count the number of occurrences of 7 in a number given by the user

while (a) {
b.push(a % 10);
a = Math.floor(a / 10);
if (b == 7) {
n = n + 1;
}
console.log("<br><br>number of 7's:" + n);
}
This is what I have come up with. The output is one of the numbers has seven; if not, then zero. I want the program to count the number of times seven appears in a number.
You can convert the number to a string, and then count how many times a character = 7:
let n = 7326577
let cnt = 0;
let strN = '' + n;
for(let c of strN)
if(c == '7')
cnt ++
console.log('Number of 7\'s in number: ' + cnt)
Following you approach you need to store the last digit to a different variable and use that for checking if it is a 7
var a = 709728457;
var b = [];
var n = 0;
while (a) {
const lastDigit = a % 10;
b.push(lastDigit); // if you still need to store all digits
a = Math.floor(a / 10);
if (lastDigit == 7) {
n = n + 1;
}
}
console.log("number of 7's:" + n);
var a = 7686774737
var no = String(a).split('').filter(e=>e==7).length;
console.log(no)

Using a recursive function to find the factorial of a given integer

I'm trying to make a recursive function to print the factorial of a given integer. Ask the user to enter a positive integer and then display the output on a page. For example, if the user enters 5, the output must be
5 × 4 × 3 × 2 × 1 = 120
var integer = prompt("Enter a positive integer.");
function factorialize(num) {
if(num == 0 || num == 1) {
return 1;
}
else {
return num + " x " + factorialize(num-1) + num * factorialize(num-1);
}
}
document.write(factorialize(integer));
You can pass a runningTotal of the sum so far to each recursive call. You can also keep the solution compact using template literals.
function factorialize(n, runningTotal = 1) {
if (n === 1) return `1 = ${runningTotal}`;
return `${n} x ${factorialize(n - 1, runningTotal * n)}`;
}
console.log(factorialize(5));
You could handover the parts of product and result.
function factorialize(num, product = 1, result = '') {
return num === 0 || num === 1
? result + (result && ' x ') + num + ' -> ' + product
: factorialize(num - 1, product * num, result + (result && ' x ') + num);
}
console.log(factorialize(5));
console.log(factorialize(2));
console.log(factorialize(1));
console.log(factorialize(0));
I think make that recursively is quite confused:
function factorialize(n, expression = '', result = 0) {
if (n < 0) {
return null
} else if (n === 0) {
return (expression || n) + " = " + result
}
const newExpression = result ? expression + " x " + n : n
const newResult = !result ? n : result * n
return factorialize(n - 1, newExpression, newResult)
}
console.log(factorialize(5))
Is better to segregate the responsibilities:
function factorial(n) {
let fact = 1
if (n < 0) {
console.warn("Error");
return 0
} else {
for (let i = n; i > 0; i--) {
fact = fact * i;
}
}
return fact
}
function factorialExpression(n) {
let expression = ""
if (n < 0) {
console.warn("Error");
return ""
} else {
for (let i = n; i > 0; i--) {
expression += (i < n ? " x " : "") + i
}
}
return expression
}
function factorialize(n) {
if (n === 0 || n === 1) {
return n + " = " + n
} else if (n > 1) {
return factorialExpression(n) + " = " + factorial(n)
}
return null
}
console.log(factorialize(5))

Format numbers in comma separated value

I am using javascript to format the number with commas , it was working very fine.
But now the problem is if a value is comming in negative for example : -792004
It is returning the output like : -,792,004 that is comma is in the start.
How can I modify this method ?
Here is my code :
function Comma(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0))
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
else
output += ',' + number.substring(mod + 3 * i, mod + 3 * i + 3);
}
return (output);
} else return number;
}
The simplest way I know which will helps you is toLocaleString() method on number:
var x = 10033001;
var y = -10033001;
console.log(x.toLocaleString(), y.toLocaleString());
But for correction of your code, you can remove number sign with Math.abs and add it after with Math.sign.
var sign = Math.sign(number);
number = Math.abs(number);
// Do the conversion
return (sign < 0) ? ("-" + output) : output;
Try this:
const comma = function(number) {
const prefix = number < 0 ? '-' : ''
number = String(Math.abs(number))
if (number.length > 3) {
const mod = number.length % 3
let output = (mod > 0 ? (number.substring(0,mod)) : '')
for (let i = 0; i < Math.floor(number.length / 3); i++) {
if (mod === 0 && i === 0)
output += number.substring(mod+ 3 * i, mod + 3 * i + 3)
else
output+= ',' + number.substring(mod + 3 * i, mod + 3 * i + 3);
}
return prefix + output
} else {
return prefix + number
}
}
If the number is negative, it assigns - to prefix. Then it changes number to its absolute value (Math.abs(number)). In the end it returns value with prefix.

How to "summarize" an array of integers to a string with ranges?

Lets say you have input Array=[1,2,3,5,7,9,10,11,12,15]
The output should be 1-3,5,7,9-12,15
Im looking for feedback on my attempt and other possible solutions.
Heres my attempt in javascript:
var min = 0;
var max = -1;
function summarize(array) {
var sumString = "";
var prevVal = -1;
array.forEach(function(currVal, index) {
if (index > 0) {
prevVal = array[index - 1];
}
if (index === 0) {
min = currVal;
max = currVal;
} else if (currVal - prevVal === 1) {
max = currVal;
} else if (min !== max && max !== -1) {
sumString += min + "-" + max + (index < array.length - 1 ? "," : "");
min = currVal;
max = -1;
} else {
sumString += min + (index < array.length - 1 ? "," : "");
}
if (index === array.length - 1) {
if (max === -1) {
sumString += "," + min;
} else {
sumString += min + "-" + max;
}
}
});
return sumString;
}
Here is a slightly shorter implementation:
var i = 0, prev, arr = [1,2,3,5,7,9,10,11,12,15], out = [];
for(i=0; i<arr.length; prev = arr[i], i++) {
// if the current number is not prev+1, append it to out
// Note that we are adding it as a string, to ensure that
// subsequent calls to `split()` (see else part) works
if(prev !== arr[i] - 1) out.push(String(arr[i]));
// if the current number is prev+1, modify the last value
// in out to reflect it in the RHS of - (hyphen)
else out[out.length - 1] = [out[out.length - 1].split('-')[0], String(arr[i])].join('-');
}
// out => ["1-3", "5", "7", "9-12", "15"]
Another possible solution for positive numbers in ascending order. It features Array.prototype.reduce.
var array = [1, 2, 3, 5, 7, 9, 10, 11, 12, 15, 23, 24],
result = [];
array.reduce(function (r, a) {
result.push(r + 1 - a ? String(a) : result.pop().split('-')[0] + '-' + String(a));
return a;
}, array[0]);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Another possible solution :
var points = [1,2,3,5,6,31,7,9,10,11,12,15];
points.sort(function(a, b){return a-b}); //sort array in asc
var resultArr=[];
var max; var min;
for(i=0;i<points.length;i++) //loop
{
if(i==0)
{
min=points[i]; //lowest number in arr
max=points[i]+1; //assign next value
}
else
{
if(max==points[i]) //if value matches continue
max=points[i]+1;
else //next value is not an incremental one so push it to result arr
{
max=max-1;
resultArr.push(min+(min!=max? "-"+ max :""));
min=points[i];
max=points[i]+1;
}
if(i==points.length-1) //last element of the arr so push it to result arr
{
max=max-1;
resultArr.push(min+(min!=max? "-"+ max :""));
}
}
}
alert(resultArr);
First step uses dashes to separate sequential numbers and commas if they aren't. Second step replaces -#- with -.
var X = [1,2,3,5,7,9,10,11,12,15];
var S = '' + X[0];
for (var i = 1; i < X.length; i++) {
S += (X[i] == X[i - 1] + 1)? '-': ',';
S += X[i];
}
while (/-[0-9]+-/.test(S))
S = S.replace(/-[0-9]+-/g, '-');
alert(S);
For a sequence like 1,2,5,6 will output 1-2,5-6 which might not be what you're looking for, so an optional third step would be to replace #-#+1 with #,#+1, i.e. restore the comma:
for (var i = 1; i < X.length; i++)
S = S.replace(X[i - 1] + '-' + X[i], X[i - 1] + ',' + X[i]);
I ran into this problem recently, after some reflection, I noticed 3 different transformations: (1) Group consecutive numbers; (2) Transform groups into strings representing the ranges; (3) Join range strings on comma.
function summarizeRange(items) {
const sorted = items.slice(0).sort((a, b) => a - b);
return sorted
.slice(1)
.reduce((range, item) => {
const rangedIndex = range.reduce((ranged, rangedCollection, index) =>
rangedCollection.indexOf(item - 1) > -1 ? index : ranged,
-1
);
if (rangedIndex > -1) {
range[rangedIndex] = range[rangedIndex].concat(item);
return range;
}
return range.concat([
[item]
]);
}, [
[sorted[0]]
])
.map(range => range.length > 1 ?
'' + range[0] + '-' + range[range.length - 1] :
'' + range[0]
)
.join(',');
}
console.log(summarizeRange([0,3,2,6,19,20,22,21,1]));

Convert integer to alpha ordered list equivalent

I need to a function to convert an integer to the equivalent alpha ordered list index. For example:
1 = a
2 = b
.
.
.
26 = z
27 = aa
28 = ab
.
.
etc.
Currently I have the following which almost works but there's a small logic error somewhere that makes it not quite get it right (it goes ax, ay, bz, ba, bb, bc...):
function intToAlpha( int ) {
var asciiStart = 97,
alphaMax = 26,
asciiCode,
char,
alpha = '',
place,
num,
i;
for ( i = 0; Math.pow(alphaMax, i) < int; i++ ) {
place = Math.pow(alphaMax, i);
num = Math.floor( ( int / place ) % alphaMax);
asciiCode = ( num == 0 ? alphaMax : num ) + asciiStart - 1;
char = String.fromCharCode(asciiCode);
alpha = char + alpha;
}
return alpha;
}
for (i = 1; i < 300; i++) {
console.log( i + ': ' + intToAlpha(i) );
}
This function is used in NVu/Kompozer/SeaMonkey Composer, with a small tweak to generate lower case directly:
function ConvertArabicToLetters(num)
{
var letters = "";
while (num > 0) {
num--;
letters = String.fromCharCode(97 + (num % 26)) + letters;
num = Math.floor(num / 26);
}
return letters;
}
You need to make sure that you use the correct value when taking the mod.
function intToAlpha( int ) {
var asciiStart = 97,
alphaMax = 26,
asciiCode,
char,
alpha = "";
while(int > 0) {
char = String.fromCharCode(asciiStart + ((int-1) % alphaMax));
alpha = char + alpha;
int = Math.floor((int-1)/26);
}
return alpha;
}
A while back I needed the same thing in SQL, so I asked (and answered) the question Multi-base conversion - using all combinations for URL shortener.
The thing that is making it complicated is that it's not a straight base conversion, as there is no character representing the zero digit.
I converted the SQL function into Javascript:
function tinyEncode(id) {
var code, value, adder;
var chars = 'abcdefghijklmnopqrstuvwxyz';
if (id <= chars.length) {
code = chars.substr(id - 1, 1);
} else {
id--;
value = chars.length;
adder = 0;
while (id >= value * (chars.length + 1) + adder) {
adder += value;
value *= chars.length;
}
code = chars.substr(Math.floor((id - adder) / value) - 1, 1);
id = (id - adder) % value;
while (value > 1) {
value = Math.floor(value / chars.length);
code += chars.substr(Math.floor(id / value), 1);
id = id % value;
}
}
return code;
}
Demo: http://jsfiddle.net/Guffa/mstBe/

Categories