{{ message }}

Instantly share code, notes, and snippets.

# iconifyit/valid-number.js

Created Jan 31, 2020
Solution to "Is it a valid number coding test". See the first comment below for test cases.
 /** * The main function. * @param s * @returns {boolean} */ function isNumber(s) { s = s.trim(); var chars = new Set(s); // Set a sequence point so we knoww var kSEQ = ';'; if (chars.has(kSEQ)) return false; s += kSEQ; var tokens = new Set('0123456789+-.e'), len = s.length, c = '', e = 'e', p = '+', m = '-', d = '.', i = 0, hasE = false, hasS = false, hasD = false, hasN = false; c = s.charAt(i); while (c !== kSEQ) { // This is not a valid token if (! tokens.has(c)) return false; // Is this a sign? else if (c === p || c === m) { // 1 ) If we have seen the sign before, the number is invalid. // 2 ) If we just saw a number, it is invalid. // 3 ) If we have seen `.` but not `e`, it is invalid. if (hasS) return false; if (hasN) return false; if (hasD && ! hasE) return false; // 1 ) Mark the sign. hasS = true; } // Is this a decimal? else if (c === d) { // 1 ) If we have seen the decimal already, the num is invalid. if (hasD) return false; // 1 ) Mark the `.` hasD = true; } // Is this an `e`? else if (c === e) { // 1 ) If we have seen `e` before, the num is invalid. // 2 ) If we have not seen a number, it is invalid. if (hasE) return false; if (! hasN) return false; // 1 ) We can reset the sign value after `e` // 2 ) Mark the `.` as seen (skips useless comparisons) // 3 ) Reset the number marker. // 4 ) Mark the `e` hasS = false; hasD = true; hasN = false; hasE = true; } // Otherwise, it must be a number, just keep reading. else { hasN = true; } c = s.charAt(++i); } return hasN; }

### iconifyit commented Jan 31, 2020 • edited

 ```var tests = [ ".e1", ".2e81", "46.e3", " -.", "-1.", "1.-", "1-2", " ", "3.", ".", "e", "+", "-", ".1", "0", " 0.1 ", "abc", "1 a", "2e10", " -90e3 ", " 1e", "e3", " 6e-1", " 6-e1", " 99e2.5 ", "53.5e93", " --6 ", "-+3", "95a54e53", "0.0", "1.2", "3", "0.0", "1.2.3", ".2", "1.", "1e2", "3.5e4e", ".2e81", "1.2345E-02", "1--2", "1++2", "1+-2", "1-+2", "2.3+e2", "2.3e+2", "2e.3", "3.456e4", "0", "0.0", "0.e0", "0.e-0", "0.e+0", "1-2", "1+2", "2e0", "2e-0", "2e+0", "2e1.2", ".e-0", "1..2", "1-.2", "1--", "1++", "+1+", "+1-", "-1-", "-1+", "-.3e6", " -.7e+0435", "166e-02767", "166e-02", "166e-027" ]; var expects = [ false, true, true, false, true, false, false, false, true, false, false, false, false, true, true, true, false, false, true, true, false, false, true, false, false, true, false, false, false, true, true, true, true, false, true, true, true, false, true, false, false, false, false, false, false, true, false, true, true, true, true, true, true, false, false, true, true, true, false, false, false, false, false, false, false, false, false, false, true, true, true, true, true ]; ```

### iconifyit commented Jan 31, 2020

 To use the test data, create a loop to call `isNumber(test)` on each item in the `tests` array and compare the result to the same item in the `expects` array. ```tests.map(function(test, i) { console.log(isNumber(test), expects(i)); }```