0

I have an array called userInput that I am pushing my input to eventually perform an eval() calculation on.

I am adding the decimal function but need to test if a number already has a decimal in my array to avoid something like 3.00.00.00.

My current function

function addPeriod() {
    if((inputArray.length == 0) || inputArray[inputArray.length -1] == '.') {
        //do nothing
    } else {
        inputArray.push('.');
        console.log(inputArray);
        screenText.append('.');
    }
}

The way my current userInput array looks now during operation once I use userInput.join('') is something like 3 + 2.00 / 1 etc... I know I need to use a regex method but not sure of the pattern that would eliminate the unwanted decimal occurrence. Thanks for the help.

Hardik Shah
  • 4,042
  • 2
  • 20
  • 41
Daniel Bailey
  • 105
  • 1
  • 2
  • 12
  • [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)? Why do you need to add a decimal point? – TypeIA Jul 16 '18 at 19:14
  • I don't need to add one, I am just trying to keep users from entering an unnecessary decimal point that will throw an error in the eval function – Daniel Bailey Jul 16 '18 at 19:22

2 Answers2

1

You could split the input string on a decimal and count the length. Any input with 1 or 0 decimals should have a length of 2 or less.

var test = "3.0"   // Valid, return true
var test2 = ".3.0" // Invalid, return false
var test3 = "30"   // Valid, return true

console.log(test.split('.').length <= 2) 
console.log(test2.split('.').length <= 2)
console.log(test3.split('.').length <= 2)

Edit: While I personally prefer the readability and feel of the Regex answer, splitting is significantly faster when searching a string for existence of a certain character.

Here you can see a split() vs regex() speed test:

var i = 0;

var split_start = new Date().getTime();
while (i < 30000) {
  "1234,453,123,324".split(",").length -1;
  i++;
}
var split_end = new Date().getTime();
var split_time = split_end - split_start;


i= 0;
var reg_start = new Date().getTime();
while (i < 30000) {
  ("1234,453,123,324".match(/,/g) || []).length;
  i++;
}
var reg_end = new Date().getTime();
var reg_time = reg_end - reg_start;

alert ('Split Execution time: ' + split_time + "\n" + 'RegExp Execution time: ' + reg_time + "\n");
Woohoojin
  • 674
  • 1
  • 4
  • 19
  • Be careful with "speed tests" like this. By using the same string in each iteration of the loop and by not using the result of the counts anywhere you're giving the optimizer very easy ways to completely defeat your benchmark. You may get lucky if the code finishes quickly enough that the hotspot profiler doesn't get around to optimizing the code. In any case, if performance is the issue ([it probably isn't](http://wiki.c2.com/?PrematureOptimization)) and the input is already in an array, counting character matches in a loop is _much_ faster than `split()`. – TypeIA Jul 16 '18 at 20:03
  • Copy pasted the benchmark from a response with quite a few upvotes from the thread I linked, didn't really analyze it.I agree that the performance aspect of this is negligible, I was mostly making an argument against using regular expressions, not an argument for choosing split() as the be all end all solution, I'll edit my response to come across with that more clearly – Woohoojin Jul 16 '18 at 20:07
  • The benchmark code on that thread was posted twice with a combined vote total of 4 (actually 2 now that I've downvoted both copies). That's not very many relative to a question with 361 votes. – TypeIA Jul 16 '18 at 20:32
0

This is the regex to test multiple dots:

var text = "3.0.0";
var text1 = "3.0.00.00";
var text2 = "3.0";
var text3 = ".3.0";
var text4 = "30";
console.log(/^\d+(\.\d{0,2})?$/.test(text));
console.log(/^\d+(\.\d{0,2})?$/.test(text1));
console.log(/^\d+(\.\d{0,2})?$/.test(text2));
console.log(/^\d+(\.\d{0,2})?$/.test(text3));
console.log(/^\d+(\.\d{0,2})?$/.test(text4));

Hope, this may help you.

Hardik Shah
  • 4,042
  • 2
  • 20
  • 41