Javascript autoincrement index - javascript

I need to create a function or use if is possible an already made library to auto increment an index. For example if it starts with 'A' it has to be incremented to 'Z' and after 'Z' it has to start from 'A1' and as soon as . . .'B1','C1', ... 'Z1', 'A2','B2',... . Does exist something like this already made ?
My idea is this, but start from 'A' and don't add number . . .
function nextChar(cont,letter) {
if (cont === 0){return letter;}
else {
letter=letter.charCodeAt(0) + 1;
return String.fromCharCode(letter);
}
}

One of many options:
function nextIndex(idx) {
var m = idx.match(/^([A-Z])(\d*)$/)
if(!m)
return 'A';
if(m[1] == 'Z')
return 'A' + (Number(m[2] || 0) + 1);
return String.fromCharCode(m[1].charCodeAt(0) + 1) + m[2];
}
var a = "";
for(i = 0; i < 100; i++) {
a = nextIndex(a)
document.write(a + ", ")
}

This one's less efficient than georg's but maybe easier to understand at first glance:
for (var count = 0, countlen = 5; count < countlen; count++) {
for (var i = 65, l = i + 26; i < l; i++) {
console.log(String.fromCharCode(i) + (count !== 0 ? count : ''));
}
}
DEMO

Allow me to propose a solution more object-oriented:
function Index(start_with) {
this.reset = function(reset_to) {
reset_to = reset_to || 'A';
this.i = reset_to.length > 1 ? reset_to[1] : 0; // needs more input checking
this.c = reset_to[0].toUpperCase(); // needs more input checking
return this;
};
this.inc = function(steps) {
steps = steps || 1;
while(steps--) {
if (this.c === 'Z') {
this.i++;
this.c = 'A';
} else {
this.c = String.fromCharCode(this.c.charCodeAt(0) + 1);
}
}
return this;
};
this.toString = function() {
if (this.i === 0) return this.c;
return this.c + '' + this.i;
};
this.reset(start_with);
}
var a = new Index(); // A
console.log('a = ' + a.inc(24).inc().inc()); // Y, Z, A1
var b = new Index('B8'); // B8
console.log('a = ' + a.reset('Y').inc()); // Y, Z
console.log('b = ' + b); // B8

Another way to think about this is that your "A1" index is just the custom rendering of an integer: 0='A',1='B',26='A1',etc.
So you can also overload the Number object to render your index. The big bonus is that all the math operations still work since your are always dealing with numbers:
Number.prototype.asIndex = function() {
var n = this;
var i = Math.floor(n / 26);
var c = String.fromCharCode('A'.charCodeAt(0) + n % 26);
return '' + c + (i ? i : '');
}
Number.parseIndex = function(index) {
var m;
if (!index) return 0;
m = index.toUpperCase().match(/^([A-Z])(\d*)$/);
if (!m || !m[1]) return 0;
return Number((m[1].charCodeAt(0) - 'A'.charCodeAt(0)) + 26 * (m[2] ? m[2] : 0));
};
var c = 52;
var ic = c.asIndex();
var nc = Number.parseIndex(ic);
console.log(c+' = '+ic+' = '+nc); // 52 = A2 = 52
If you go this way I would try to check if the new methods don't already exist first...

Related

Javascript while loop (Card deck simulation)

I am having an issue with the following code that simulates a card deck.
The deck is created properly (1 array containing 4 arrays (suits) containing 13 elements each (face values)) and when I use the G.test(); function it is correctly pulling 13 random cards but then returns 39x "Empty" (A total of 52).
I hate to ask for help, but I have left the problem overnight and then some and I still cannot find the reason that this is happening. I appreciate any and all insight that can be offered.
var G = {};
G.cards = [[], [], [], []];
G.newCard = function(v) { //currently a useless function, tried a few things
return v;
};
G.deck = {
n: function() { //new deck
var x; var list = [];
list.push(G.newCard("A"));
for (x = 2; x <= 10; x += 1) {
list.push(G.newCard(x.toString()));
}
list.push(G.newCard("J"), G.newCard("Q"), G.newCard("K"));
for (x = 0; x < G.cards.length; x += 1) {
G.cards[x] = list;
}
},
d: function() { //random card - returns suit & value
var s; var c; var v; var drawn = false; var n;
s = random(0, G.cards.length);
c = random(0, G.cards[s].length);
n = 0;
while (!drawn) {
if (G.cards[s].length > 0) {
if (G.cards[s][c]) {
v = G.cards[s].splice(c, 1);
drawn = true;
} else {
c = random(0, G.cards[s].length);
}
} else {
s = (s + 1 >= G.cards.length) ? 0 : s + 1;
n += 1;
console.log(s);
if (n >= G.cards.length) {
console.log(n);
return "Empty";
}
}
}
return {s: s, v: v[0]};
},
}; //G.deck
G.test = function() {
var x; var v;
G.deck.n();
for (x = 0; x < 52; x += 1) {
v = G.deck.d();
console.log(v);
}
};
Replace
for (x = 0; x < G.cards.length; x += 1) {
G.cards[x] = list;
}
with
for (x = 0; x < G.cards.length; x += 1) {
G.cards[x] = list.slice();
}
as this prevents all elements of G.cards[x] binding to the same (single) array instance.
If all elements bind to the same instance, mutating one element equals mutating all elements. list.slice() creates a new copy of list and thus a new array instance to prevent the aforementioned issue.
I won't go through your code, but I built a code that will do what you wanted. I only built this for one deck and not multiple deck play. There are two functions, one will generate the deck, and the other will drawn cards from the deck, bases on how many hands you need and how many cards you wanted for each hand. One a card is drawn, it will not be re-drawn. I might publish a short article for how a card dealing program work or similar in the short future at http://kevinhng86.iblog.website.
function random(min, max){
return Math.floor(Math.random() * (max - min)) + min;
}
function deckGenerate(){
var output = [];
var face = {1: "A", 11: "J", 12: "Q", 13: "K"};
// Heart Space Diamond & Club;
var suit = ["H", "S", "D", "C"];
// Delimiter between card identification and suit identification.
var d = "-";
for(i = 0; i < 4; i++){
output[i] = [];
for(ind = 0; ind < 13; ind++ ){
card = (ind + 1);
output[i][ind] = (card > 10) || (card === 1)? face[card] + d + suit[i] : card.toString() + d + suit[i];
}
}
return output;
}
function randomCard(deck, hand, card){
var output = [];
var randS = 0;
var randC = 0;
if( hand * card > 52 ) throw("Too many card, I built this for one deck only");
for(i = 0; i < hand; i++){
output[i] = [];
for(ind = 0; ind < card; ind++){
randS = random(0, deck.length);
randC = random(0, deck[randS].length);
output[i][ind] = deck[randS][randC];
deck[randS].splice(randC,1);
if(deck[randS].length === 0) deck.splice(randS,1);
}
}
document.write( JSON.stringify(deck, null, 2) );
return output;
}
var deck = deckGenerate()
document.write( JSON.stringify(deck, null, 2) );
document.write("<br><br>");
var randomhands = randomCard(deck, 5, 8);
document.write("<br><br>");
document.write("<br><br>");
document.write( JSON.stringify(randomhands, null, 2) );

Trying to write a javascript function that counts to the number inputted

Trying to take an integer and have it return as a
string with the integers from 1 to the number passed.
Trying to use a loop to return the string but not sure how!
Example of how I want it to look:
count(5) => 1, 2, 3, 4, 5
count(3) => 1, 2, 3
Not really sure where to even start
I would do it with a recursive function. Keep concatenating the numbers until it reaches 1.
var sequence = function(num){
if(num === 1) return '1';
return sequence(num - 1) + ', ' + num;
}
Or just:
var sequence = (num) => num === 1 ? '1' : sequence(num - 1) + ', ' + num;
You can use a for loop to iterate the number of times that you pass in. Then, you need an if-statement to handle the comma (since you don't want a comma at the end of the string).
function count(num) {
var s = "";
for(var i = 1; i <= num; i++) {
s += i;
if (i < (num)) {
s += ', ';
}
}
return s;
}
JSBin
Try this:
function count(n) {
var arr = [];
for (var i = 1; i<=n; i++) {
arr.push(i.toString());
}
return arr.toString();
}
Here's a non-recursive solution:
var sequence = num => new Array(num).fill(0).map((e, i) => i + 1).toString();
here is a goofy way to do it
function count(i)
{
while (i--) {
out = (i + 1) + "," + this.out;
}
return (out + ((delete out) && "")).replace(",undefined", "");
}
Quite possibly the most ridiculous way, defining an iterator:
"use strict";
function count ( i ) {
let n = 0;
let I = {};
I[Symbol.iterator] = function() {
return { next: function() { return (n > i) ? {done:true}
: {done:false, value:n++} } } };
let s = "";
let c = "";
for ( let i of I ) {
s += c + i;
c = ", "
}
return s;
}
let s = count(3);
console.log(s);

returning equation with all possible parenthesis combinations and the result of each

On a recent interview, I was asked to return all possible combinations of order of operations on an input string, and the result. you should return all the ways/combinations in which you can "force" operations with parenthesis. I got the result (right hand side of the equation) but got stuck on the left side. how could I have done the left side and the right hand side together? Seems like two problems in one...
//input:
console.log(diffWaysToCompute("2 * 3 - 4 * 5"));
//output:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
'use strict'
function getNumbersAndOperators(str) {
var arr = str.split(" ");
var operators = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] === "-" || arr[i] === "*" || arr[i] === "+") {
operators.push(arr[i]);
arr.splice(i, 1);
// console.log(operators);
}
}
return [arr, operators];
}
// console.log(getNumbersAndOperators("2 - 1 - 1"))
var diffWaysToCompute = function (input) {
// var numbers = input.split(" ");
// console.log(numbers);
// // console.log(number);
var results = compute(input);
results.sort(function (a, b) {
return a - b;
});
//put the numbers length into valid parenthesis:
var NumbersAndOperators = getNumbersAndOperators(input);
var numbers = NumbersAndOperators[0];
console.log(numbers);
var operators = NumbersAndOperators[1];
console.log(operators);
var parens = validParentheses(numbers.length);
// console.log(numbers);
console.log(operators);
// for (var i = 0; i < parens.length; i++) {
// for (var j = 0; j < parens[i].length; j++) {
// var val = parens[i][j];
// console.log(val);
// if (val === " ") {
// var num = numbers.shift();
// parens.splice(val, 0, num);
// //starting running into infinite loops and out of time.
// j--;
// }
// }
// i--;
// }
console.log(parens);
return results;
};
function validParentheses(n) {
if (n === 1) {
return ['( )'];
}
var prevParentheses = validParentheses(n - 1);
var list = {};
prevParentheses.forEach(function (item) {
list['( ' + item + ' )'] = null;
list['( )' + item] = null;
list[item + '( )'] = null;
});
console.log(Object.keys(list))
return Object.keys(list);
}
function compute(str) {
var res = [];
var i;
var j;
var k;
var left;
var right;
var string = [];
var placed = true;
if (!/[+*-]/.test(str)) { // + - *
return [parseInt(str)];
}
for (i = 0; i < str.length; i++) {
if (/\+|\-|\*/.test(str[i])) { // + - *
left = compute(str.substring(0, i));
right = compute(str.substring(i + 1, str.length));
for (j = 0; j < left.length; j++) {
for (k = 0; k < right.length; k++) {
if (str[i] === '+') {
res.push(parseInt(left[j] + right[k]));
} else if (str[i] === '-') {
// string.push("(" + str[i-2], str[i+2] + ")");
res.push(parseInt(left[j] - right[k]));
} else if (str[i] === '*') {
res.push(parseInt(left[j] * right[k]));
}
}
}
}
}
// console.log(string);
return res;
}
console.log(diffWaysToCompute("2 - 1 - 1"));
console.log(diffWaysToCompute("2 * 3 - 4 * 5"));
I never had to do such silly things, so let me try my teeth at it now.
(Caveat as always: it's highly simplified and without any checks&balances!)
The parser is the simplest thing here:
/*
Use of strings instead of ASCII codes for legibility.
I changed x - y to x + (-y) not only for convenience
but for algebraic correctness, too.
#param a array number nodes
#param o array operator nodes
*/
function parse(s,a,o){
var fnum = 0;
var uminus = false
for(var i=0;i<s.length;i++){
switch(s[i]){
case '-': uminus = true;
a.push(fnum);
o.push('+');
fnum = 0;
break;
case '+':
case '*':
case '/': if(uminus){
uminus = false;
fnum *= -1;
}
a.push(fnum);
o.push(s[i]);
fnum = 0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': fnum = fnum * 10 + parseInt(s[i]);
break;
default: break;
}
}
//assuming symmetry
a.push(fnum);
}
The (-generation took me some time, too much time--I cheated here ;-)
/*
Found in an old notebook (ported from C)
Algo. is O(n^2) and can be done faster but I
couldn't be a...ehm, had no time, sorry.
#idx int index into individual result
#n int number of groups
#open int number of opening parentheses
#close int number of closing parentheses
#a array individual result
#all array space for all results
*/
function makeParens(idx,n,open,close,a,all){
if(close == n){
all.push(a.slice(0));
return;
} else {
if(open > close){
a[idx] = ')';
makeParens(idx+1,n,open,close+1,a,all);
}
if(open < n){
a[idx] = '(';
makeParens(idx+1,n,open+1,close,a,all);
}
}
}
And now? Yepp, that took me a while:
/*
The interesting part
Not very optimized but working
#s string the equation
#return array nicely formatted result
*/
function parenthesing(s){
var nums = [];
var ops = [];
var all = [];
var parens = [];
// parse input into numbers and operators
parse(input,nums,ops);
/*
Rules:
1) out-most parentheses must be open in direction to center
e.g.: (1+2+3), 1+(2+3), 1+(2+3)+4
but not: 1)+(2+3)+(4
so: first parenthesis on the left side must be open and
the last parenthesis on the right side must be close
2) parentheses in direct neighborhood to a number must be
open in direction to the number (multiplication is
not mutual)
e.g.: 1+(2+3)+4, but not: 1+2(+3+4)
3) parentheses in direct neighborhood to an operator must be
closed in direction to the operator (multiplication is
not mutual)
e.g.: 1+(2+3)+4, but not: 1+2(+3+)4
*/
// build combinations separately not in-line
// it's already a mess, no need to add more
makeParens(0,nums.length,0,0,[],parens);
// You may take a look at the raw material here
// console.log(parens.join("\n"));
for(var i= 0;i<parens.length;i++){
var term = [];
// work on copies to reduce pointer juggling
var _ops = ops.slice(0);
var _nums = nums.slice(0);
for(var j=0;j<parens[i].length;j++){
if(parens[i][j] === '('){
term.push("(");
// rule 3
if(parens[i][j+1] === ')'){
term.push(_nums.shift());
}
// rules 1,2
else {
term.push(_nums.shift());
term.push(_ops.shift());
}
}
if(parens[i][j] === ')'){
term.push(")");
// rules 2,3
if(parens[i][j+1] !== ')')
term.push(_ops.shift());
}
}
// some pretty printing
term = term.join("");
// eval() because I didn't want to write a parser
// but if you need one...
all.push(term + " = " + eval(term));
}
return all;
}
I'm not sure if I would get hired with that abomination. Ah, to be honest: I doubt it.
But I hope it is at least a little bit helpful.
Yikes. That was tricky. Good challenge. I'm sure this could be cut way down, but it works. I used lodash and broke the various functions down to make it more flexible. Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/3e8g22Lk/8/
Oops - had to add parseInt to the addition so it doesn't add as strings.
/*
//input:
diffWaysToCompute("2 * 3 - 4 * 5");
//output:
(2*(3-(4*5))) = -34 - 2,1,0
((2*3)-(4*5)) = -14 - 0,2,1 & 2,0,1
((2*(3-4))*5) = -10 - 1,0,2
(2*((3-4)*5)) = -10 - 1,2,0
(((2*3)-4)*5) = 10 - 0,1,2
*/
'use strict'
var diffWaysToCompute = function(str) {
var opsAvailable = ['+','-','/','*'],
numbers = [],
operators = [],
getNumbersAndOperators = function(str) {
var arr = str.split(" ");
for (var i in arr) {
if ( opsAvailable.indexOf( arr[i] ) > -1 ) {
operators.push( arr[i] );
} else {
numbers.push( arr[i] );
}
};
return;
},
permutator = function(range) {
var results = [];
function permute(arr, memo) {
var cur,
memo = memo || [];
for (var i in arr) {
cur = arr.splice(i, 1);
if (arr.length === 0) results.push(memo.concat(cur));
permute(arr.slice(), memo.concat(cur));
arr.splice(i, 0, cur[0]);
}
return results;
}
return permute(_.range(range));
},
equations = function( perms ) {
var results = [];
_.each(perms, function( perm, k ) {
results[k] = nest ( perm );
});
return results;
},
nest = function( perm ) {
var eqs = eqs || [],
ref = ref || _.range(perm.length).map(function () { return undefined }),
eq,
target = undefined;
for (var i in perm) {
var cur = perm[i],
next = perm[i] + 1,
n1 = numbers[ cur ],
n2 = numbers[ next ],
r1 = ref[ cur ],
r2 = ref[ next ];
if ( r1 !== undefined) n1 = eqs [ r1 ];
if ( r2 !== undefined) n2 = eqs [ r2 ];
var rNew;
rNew = eqs.length;
for (var x in ref ) {
if ( ( ref[ x ] !== undefined ) && ( ref[ x ] == r1 || ref[ x ] == r2 ) ) ref[ x ] = eqs.length;
};
ref[ cur ] = ref[ next ] = eqs.length;
eqs.push({
ops: operators[ cur ],
nums: [ n1, n2 ]
});
};
return eqs[ eqs.length - 1 ];
},
calculations = function ( eqs ) {
var results = []
_.each(eqs, function(equation) {
results.push(calculate( equation ));
});
return results;
},
calculate = function( eq ) {
var result = {
text: ""
};
// result.eq = eq;
result.text += "( ";
result.total = eq.nums[ 0 ];
if ( _.isObject(result.total) ) {
var result1 = calculate( result.total );
result.total = result1.total;
result.text += result1.text;
} else {
result.text += eq.nums[ 0 ];
}
_.each(eq.ops, function (op, k) {
var num = eq.nums[ k + 1 ];
result.text += " " + op + " ";
if ( _.isObject(num) ) {
var result2 = calculate( num );
num = result2.total;
result.text += result2.text;
} else {
result.text += num;
}
if ( op === '+') result.total = parseInt(result.total) + parseInt(num);
if ( op === '-') result.total = result.total - num;
if ( op === '/') result.total = result.total / num;
if ( op === '*') result.total = result.total * num;
});
result.text += " )";
return result;
},
display = function( as ) {
var target = document.getElementById('result');
target.innerHTML += '<h3 class="problem">String given: ' + str + '</h3>';
target.innerHTML += '<h4>Permutations</h4>';
_.each( as, function(a) {
target.innerHTML += '<div class="permutation">';
target.innerHTML += ' <span class="formula">' + a.text + '</span> = ';
target.innerHTML += ' <span class="total">' + a.total + '</span>';
target.innerHTML += '</div>';
});
},
perms,
eqs,
answers;
getNumbersAndOperators(str);
perms = permutator( operators.length );
eqs = equations( perms );
answers = calculations( eqs );
answers = _.uniq(answers, 'text');
display(answers);
return answers;
};
console.log(diffWaysToCompute("2 * 3 - 4 * 5"));

Create range of letters and numbers

I'm creating a form where users can input a range. They are allowed to input letters and numbers. Some sample input:
From: AA01
To: AZ02
Which should result in:
AA01
AA02
AB01
AB02
And so on, till AZ02
And:
From: BC01
To: DE01
Should result in:
BC01
BD01
BE01
CC01
CD01
CE01
Etc
I managed to get it working for the input A01 to D10 (for example)
jsFiddle
However, i can't get it to work with multiple letters.
JS code:
var $from = $('input[name="from"]');
var $to = $('input[name="to"]');
var $quantity = $('input[name="quantity"]');
var $rangeList = $('.rangeList');
var $leadingzeros = $('input[name="leadingzeros"]');
$from.on('keyup blur', function () {
$(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
updateQuantity();
});
$to.on('keyup blur', function () {
$(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
updateQuantity();
});
$leadingzeros.on('click', function () {
updateQuantity();
});
function updateQuantity() {
var x = parseInt($from.val().match(/\d+/));
var y = parseInt($to.val().match(/\d+/));
var xl = $from.val().match(/[a-zA-Z]+/);
var yl = $to.val().match(/[a-zA-Z]+/);
var result = new Array();
if (xl != null && yl != null && xl[0].length > 0 && yl[0].length > 0) {
xl = xl[0].toUpperCase();
yl = yl[0].toUpperCase();
$rangeList.html('');
var a = yl.charCodeAt(0) - xl.charCodeAt(0);
for (var i = 0; i <= a; i++) {
if (!isNaN(x) && !isNaN(y)) {
if (x <= y) {
var z = (y - x) + 1;
$quantity.val(z * (a + 1));
$rangeList.html('');
for (var b = z; b > 0; b--) {
var c = ((y - b) + 1);
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
result.push(String.fromCharCode(65 + i) + c);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
}
} else if (!isNaN(x) && !isNaN(y)) {
if (x < y) {
var z = (y - x) + 1;
$quantity.val(z);
$rangeList.html('');
for (var i = z; i > 0; i--) {
var c = (y - i) + 1;
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
result.push(c);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
} else {
$rangeList.html('');
$quantity.val(0);
}
$rangeList.html('');
for (var i = 0; i < result.length; i++) {
$rangeList.append(result[i] + '<br />');
}
}
function leadingZeroes(number, size) {
number = number.toString();
while (number.length < size) number = "0" + number;
return number;
}
This is perfect for a recursive algorithm:
function createRange(from, to) {
if (from.length === 0) {
return [ "" ];
}
var result = [];
var innerRange = createRange(from.substring(1), to.substring(1));
for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(String.fromCharCode(i) + innerRange[j]);
}
}
return result;
}
Called as follows:
createRange('BC01', 'DE02'); // Generates an array containing all values expected
EDIT: Amended function below to match new test case (much more messy, however, involving lots of type coercion between strings and integers).
function prefixZeroes(value, digits) {
var result = '';
value = value.toString();
for (var i = 0; i < digits - value.length; i++) {
result += '0';
}
return result + value;
}
function createRange(from, to) {
if (from.length === 0) {
return [ "" ];
}
var result = [];
if (from.charCodeAt(0) < 65) {
fromInt = parseInt(from);
toInt = parseInt(to);
length = toInt.toString().length;
var innerRange = createRange(from.substring(length), to.substring(length));
for (var i = fromInt; i <= toInt; i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(prefixZeroes(i, length) + innerRange[j]);
}
}
} else {
var innerRange = createRange(from.substring(1), to.substring(1));
for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
for (var j = 0; j < innerRange.length; j++) {
result.push(String.fromCharCode(i) + innerRange[j]);
}
}
}
return result;
}
Please note that because of your strict logic in how the value increments this method requires exactly 4 characters (2 letters followed by 2 numbers) to work. Also, this might not be as efficient/tidy as it can be but it took some tinkering to meet your logic requirements.
function generate(start, end) {
var results = [];
//break out the start/end letters/numbers so that we can increment them seperately
var startLetters = start[0] + start[1];
var endLetters = end[0] + end[1];
var startNumber = Number(start[2] + start[3]);
var endNumber = Number(end[2] + end[3]);
//store the start letter/number so we no which value to reset the counter to when a maximum boundry in reached
var resetLetter = startLetters[1];
var resetNumber = startNumber;
//add first result as we will always have at least one
results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
//maximum while loops for saefty, increase if needed
var whileSafety = 10000;
while (true) {
//safety check to ensure while loop doesn't go infinite
whileSafety--;
if (whileSafety == 0) break;
//check if we have reached the maximum value, if so stop the loop (break)
if (startNumber == endNumber && startLetters == endLetters) break;
//check if we have reached the maximum number. If so, and the letters limit is not reached
//then reset the number and increment the letters by 1
if (startNumber == endNumber && startLetters != endLetters) {
//reset the number counter
startNumber = resetNumber;
//if the second letter is at the limit then reset it and increment the first letter,
//otherwise increment the second letter and continue
if (startLetters[1] == endLetters[1]) {
startLetters = '' + String.fromCharCode(startLetters.charCodeAt(0) + 1) + resetLetter;
} else {
startLetters = startLetters[0] + String.fromCharCode(startLetters.charCodeAt(1) + 1);
}
} else {
//number limit not reached so just increment the number counter
startNumber++;
}
//add the next sequential value to the array
results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
}
return results;
}
var results = generate("BC01", "DE01");
console.log(results);
Here is a working example, which uses your second test case
Using #Phylogenesis' code, i managed to achieve my goal.
jsFiddle demo
function updateQuantity() {
var x = parseInt($from.val().match(/\d+/));
var y = parseInt($to.val().match(/\d+/));
var xl = $from.val().match(/[a-zA-Z]+/);
var yl = $to.val().match(/[a-zA-Z]+/);
var result = new Array();
var r = createRange(xl[0], yl[0]);
var z = (y - x) + 1;
if (x <= y) {
for (var j = 0; j < r.length; j++) {
var letters = r[j];
for (var i = z; i > 0; i--) {
var c = (y - i) + 1;
if ($leadingzeros.prop('checked')) {
c = leadingZeroes(c, y.toString().length);
}
if (i == z) {
r[j] = letters + c + '<br />';
} else {
j++;
r.splice(j, 0, letters + c + '<br />');
}
}
}
} else {
for (var i = 0; i < r.length; i++) {
r[i] += '<br />';
}
}
$quantity.val(r.length);
$rangeList.html('');
for (var i = 0; i < r.length; i++) {
$rangeList.append(r[i]);
}
}
This works for unlimited letters and numbers, as long as the letters are first.
Thanks for your help!

Converting/expressing double number in non-exponent/short form in Javascript

I have a double in Javascript whose value is, for example, 1.0883076389305e-311.
I want to express it in the following form, using as example the 'bc' utility to calculate the expanded/higher precision/scale form:
$ bc
scale=400
1.0883076389305000*10^-311
.0000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000010883076389305000000000000000\
0000000000000000000000000000000000000000000000000000000000000
I need a Javascript bigint library or code to produce the same output as a string with the expanded/higher precision form of the number.
Thanks!
This is horrible, but works with every test case I can think of:
Number.prototype.toFullFixed = function() {
var s = Math.abs(this).toExponential();
var a = s.split('e');
var f = a[0].replace('.', '');
var d = f.length;
var e = parseInt(a[1], 10);
var n = Math.abs(e);
if (e >= 0) {
n = n - d + 1;
}
var z = '';
for (var i = 0; i < n; ++i) {
z += '0';
}
if (e <= 0) {
f = z + f;
f = f.substring(0, 1) + '.' + f.substring(1);
} else {
f = f + z;
if (n < 0) {
f = f.substring(0, e + 1) + '.' + f.substring(e + 1);
}
}
if (this < 0) {
f = '-' + f;
}
return f;
};
If you find a number that doesn't parse back correctly, i.e. n !== parseFloat(n.toFullFixed()), please let me know what it is!
// So long as you are dealing with strings of digits and not numbers you can
use string methods to convert exponential magnitude and precision to zeroes
function longPrecision(n, p){
if(typeof n== 'string'){
n= n.replace('*10', '').replace('^', 'e');
}
p= p || 0;
var data= String(n), mag, str, sign, z= '';
if(!/[eE]/.test(data)){
return data;
if(data.indexOf('.')== -1 && data.length<p) data+= '.0';
while(data.length<p) data+= '0';
return data;
}
data= data.split(/[eE]/);
str= data[0];
sign= str.charAt(0)== "-"? "-": "";
str= str.replace(/(^[+-])|\./, "");
mag= Number(data[1])+ 1;
if(mag < 0){
z= sign + "0.";
while(mag++) z += "0";
str= z+str;
while(str.length<p) str+= '0';
return str;
}
mag -= str.length;
str= sign+str;
while(mag--) z += "0";
str += z;
if(str.indexOf('.')== -1 && str.length<p) str+= '.0';
while(str.length<p) str+= '0';
return str;
}
var n='1.0883076389305000*10^-311';
longPrecision(n, 400);
/* returned value: (String)
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001088307638930500000000000000000000000000000000000000000000000000000000000000000000000000
*/

Categories

Resources