Created
July 5, 2019 20:28
-
-
Save JordanMajd/daab288e5edbd28af676df3fad7697e9 to your computer and use it in GitHub Desktop.
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
'use strict'; | |
// Test flatten | |
assertArray(flatten([[1, 2, [3]], 4]), [1, 2, 3, 4]); | |
assertArray(flatten([0, [[[[1]]], [[2, [3]]], 4], [5, 6]]), [0, 1, 2, 3, 4, 5, 6]); | |
// Test throws type error with array values other than integer | |
assertError(flatten, TypeError, [0, ["string", [2]]]); | |
// Test throws type error for arr | |
assertError(flatten, TypeError, undefined); | |
// Test throws type error for acc | |
assertError(flatten, TypeError, [1,2,3], "not an array"); | |
// Test throws type error for idx | |
assertError(flatten, TypeError, [1,2,3], [], "not an int"); | |
// Test idx out of range error | |
assertError(flatten, RangeError, [1,2,3], [], -1); | |
assertError(flatten, RangeError, [1,2,3], [], 100); | |
// Flatten an array of integer values. | |
function flatten(arr, acc = [], idx = 0) { | |
// Validate arguments; this is why typescript is nice. | |
if (!Array.isArray(arr) || !Array.isArray(acc) || !Number.isInteger(idx)) { | |
throw TypeError(`Invalid type for given arguments.`); | |
} | |
// Ensure idx is in range, notice arr.length is valid range for base case. | |
if (idx < 0 || idx > arr.length ) { | |
throw new RangeError(`idx: ${idx} out of bounds.`) | |
} | |
// Base case, we've reached the end | |
if (idx === arr.length) { | |
return acc; | |
} | |
// Set cur to current index. | |
let cur = arr[idx]; | |
// Ensure cur is of type integer or array. | |
if (!Number.isInteger(cur) && !Array.isArray(cur)) { | |
throw TypeError(`Array values must be of type Integer or Array.`); | |
} | |
// If cur is an Array, recurse to break down to value. | |
if (Array.isArray(cur)) { | |
cur = flatten(cur); | |
} | |
// Recurse, adding current value to accumulator and incrementing to next val | |
return flatten(arr, acc.concat(cur), ++idx); | |
} | |
// Mini Tests Suite | |
// Assert equality of two arrays | |
function assertArray(arr, exp) { | |
assert(arr, exp, (a, b) => { | |
let passed = false; | |
if (arr.length === exp.length) { | |
passed = true; | |
for (let i = 0; i < arr.length; i++) { | |
if (arr[i] !== exp[i]) { | |
passed = false; | |
} | |
} | |
} | |
return passed; | |
}); | |
} | |
// Assert correct error type is thrown | |
function assertError(method, errorType, ...args) { | |
let errorName; | |
try { | |
method.apply(undefined, args); | |
} catch (e) { | |
errorName = e.name; | |
} finally { | |
assertValue(errorName, errorType.name); | |
} | |
} | |
// assert equality for two values | |
function assertValue(val1, val2){ | |
assert(val1, val2, (a, b) => a === b); | |
} | |
// assert function returns true | |
function assert(val1, val2, fn) { | |
try { | |
if (fn(val1, val2)){ | |
console.log(`Test Passed! ${val1} === ${val2}`); | |
} else { | |
throw new Error(`${val1} !== ${val1}`); | |
} | |
} catch (e) { | |
console.error(`Test Failed! ${e}`); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment