Skip to content

Instantly share code, notes, and snippets.

@JordanMajd
Created July 5, 2019 20:28
Show Gist options
  • Save JordanMajd/daab288e5edbd28af676df3fad7697e9 to your computer and use it in GitHub Desktop.
Save JordanMajd/daab288e5edbd28af676df3fad7697e9 to your computer and use it in GitHub Desktop.
'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