Created
January 31, 2018 19:04
-
-
Save cdosborn/9b7c64e8f935f6d24caf7ffd958d1415 to your computer and use it in GitHub Desktop.
Javascript comparsions: Is variable a number?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let testCases = [ | |
['""', "", false], | |
['"\\t"', "\t", false], | |
['" "', " ", false], | |
['"Infinity"', "Infinity", false], | |
['"123abc"', "123abc", false], | |
['"abc123"', "abc123", false], | |
['"+123"', "+123", false], | |
['"1."', "1.", true], | |
['"."', ".", false], | |
['"01"', "01", true], | |
['"-123"', "-123", true], | |
["+1", +1, true], | |
["-1", -1, true], | |
["null", null, false], | |
["true", true, false], | |
["false", false, false], | |
["-Infinity", -Infinity, false], | |
["Infinity", Infinity, false], | |
["+Infinity", +Infinity, false], | |
['"-0"', "-0", false], | |
["NaN", NaN, false], | |
["[]", [], false], | |
["{}", {}, false], | |
["() => {}", () => {}, false] | |
]; | |
let testSolutions = [ | |
v => parseFloat(v), | |
v => Number(v), | |
v => !isNaN(v), | |
v => isFinite(String(v)), | |
v => !isNaN(parseFloat(v)) && isFinite(v) | |
]; | |
class TestCasePerformanceTable extends React.Component { | |
static renderTableHeader(testSolutions) { | |
return ( | |
<tr> | |
<th> | |
<p>Test Case (How fast is the solution?)</p> | |
</th> | |
{testSolutions.map(f => ( | |
<th key={f.toString()}> | |
<p>{f.toString()}</p> | |
</th> | |
))} | |
</tr> | |
); | |
} | |
static averageOfNRuns(f, args, n) { | |
let sum = 0; | |
while (n > 0) { | |
const start = Performance.now(); | |
f.apply(args); | |
const end = Performance.now(); | |
sum += end - start; | |
n--; | |
} | |
return sum / n; | |
} | |
static renderTableRow(testCase, testSolutions) { | |
const [testName, input, expectedOutput] = testCase; | |
return ( | |
<tr key={testName}> | |
<td>{testName}</td> | |
{testSolutions.map(f => { | |
return ( | |
<td key={f.toString()}> | |
<p>{TestCasePerformanceTable.averageOfNRuns(f, [input], 10)}</p> | |
</td> | |
); | |
})} | |
</tr> | |
); | |
} | |
render() { | |
return ( | |
<table> | |
<thead> | |
{TestCasePerformanceTable.renderTableHeader(testSolutions)} | |
</thead> | |
<tbody> | |
{testCases.map(tc => TestCaseTable.renderTableRow(tc, testSolutions))} | |
</tbody> | |
</table> | |
); | |
} | |
} | |
class TestCaseTable extends React.Component { | |
static renderTableHeader(testSolutions) { | |
return ( | |
<tr> | |
<th> | |
<p>Test Case (Is it a number?)</p> | |
</th> | |
{testSolutions.map(f => ( | |
<th key={f.toString()}> | |
<p>{f.toString()}</p> | |
</th> | |
))} | |
</tr> | |
); | |
} | |
static renderTableRow(testCase, testSolutions) { | |
const [testName, input, expectedOutput] = testCase; | |
return ( | |
<tr key={testName}> | |
<td>{testName}</td> | |
{testSolutions.map(f => { | |
return ( | |
<td key={f.toString()}> | |
<p>{Boolean(f(input)) + ""}</p> | |
</td> | |
); | |
})} | |
</tr> | |
); | |
} | |
render() { | |
return ( | |
<table> | |
<thead>{TestCaseTable.renderTableHeader(testSolutions)}</thead> | |
<tbody> | |
{testCases.map(tc => TestCaseTable.renderTableRow(tc, testSolutions))} | |
</tbody> | |
</table> | |
); | |
} | |
} | |
class TestCaseSummaryTable extends React.Component { | |
static renderTableHeader(testSolutions) { | |
return ( | |
<tr> | |
<th /> | |
{testSolutions.map(f => ( | |
<th key={f.toString()}> | |
<p>{f.toString()}</p> | |
</th> | |
))} | |
</tr> | |
); | |
} | |
static renderAverageTimeRow(testSolutions, testCases) { | |
const averageAcrossTestCases = f => | |
testCases.reduce((totalTime, [name, input, expected]) => { | |
return ( | |
totalTime + TestCasePerformanceTable.averageOfNRuns(f, [input], 10) | |
); | |
}, 0) / testCases.length; | |
return ( | |
<tr> | |
<td> | |
<p>Performance (10 run avg) in ms</p> | |
</td> | |
{testSolutions.map(f => ( | |
<td> | |
<p>{averageAcrossTestCases(f)}</p> | |
</td> | |
))} | |
</tr> | |
); | |
} | |
static renderSuccessRateRow(testSolutions, testCases) { | |
const numSuccess = testSolution => | |
testCases.reduce((succeeded, [name, input, expected]) => { | |
return succeeded + (testSolution(input) == expected ? 1 : 0); | |
}, 0); | |
return ( | |
<tr> | |
<td> | |
<p>Test Success</p> | |
</td> | |
{testSolutions.map(f => ( | |
<td> | |
<p> | |
{numSuccess(f)} / {testCases.length} | |
</p> | |
</td> | |
))} | |
</tr> | |
); | |
} | |
render() { | |
return ( | |
<table> | |
<thead>{TestCaseTable.renderTableHeader(testSolutions)}</thead> | |
<tbody> | |
{TestCaseSummaryTable.renderSuccessRateRow(testSolutions, testCases)} | |
{TestCaseSummaryTable.renderAverageTimeRow(testSolutions, testCases)} | |
</tbody> | |
</table> | |
); | |
} | |
} | |
const root = () => { | |
return ( | |
<div> | |
<TestCaseSummaryTable /> | |
<TestCaseTable /> | |
<TestCasePerformanceTable /> | |
</div> | |
); | |
}; | |
ReactDOM.render(root(), document.querySelector("#application")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment