Last active
May 4, 2019 20:09
-
-
Save Zyst/63d3bfaecc66a792e8484a4a41fc9018 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/** | |
* For the comments marked as "NOTE" I normally wouldn't include as comments | |
* in an actual program, but I felt they were aspects that needed I'd talk | |
* about if I were explaining it in a whiteboard-type interview. | |
* | |
* I also added "array-flatten-non-verbose.js" which is what I'd show if I had to | |
* "Ship to production", and my tests were grabbing the flattenArray, and | |
* recursiveFlatten function somewhere like jest to run more formal tests | |
* | |
* https://gist.github.com/Zyst/63d3bfaecc66a792e8484a4a41fc9018#file-array-flatten-non-verbose-js | |
*/ | |
// Takes in an array, and optionally an array of existing results, for | |
// non-array items we add them to results, for array items we call ourselves | |
// then we return our flat results array | |
const recursiveFlatten = (array, results = []) => { | |
array.forEach(a => { | |
// NOTE: If we have an array, we call recursive flatten on it, passing | |
// in our results array, since this is all sequential, and arrays | |
// are shared in memory in JS this works as expected when we return | |
// results at the end of our function | |
if (Array.isArray(a)) { | |
recursiveFlatten(a, results); | |
} else { | |
// NOTE: Here, if as the spec. mentioned we wanted all items to be | |
// integers is where we would validate it. I imagined | |
// that wasn't part of the spec, but if it were I'd | |
// ask clarifying questions about it before writing | |
// the solution | |
results.push(a); | |
} | |
}); | |
return results; | |
}; | |
// Will flatten an array of arbitrarily nested items into a flat | |
// array of items. e.g. [[1,2,[3]],4] -> [1,2,3,4]. | |
const flattenArray = arrayToFlatten => { | |
// NOTE: If the item we got passed isn't an array, we should just return an empty | |
// array to avoid bad usage of this function throwing in applications, this | |
// too would be a clarifying question | |
if (!Array.isArray(arrayToFlatten)) { | |
return []; | |
} | |
return recursiveFlatten(arrayToFlatten); | |
}; | |
// This is a small utility function for testing array lengths, which is the main | |
// way I decided to test my flattenArray function | |
const expectLength = (array, expectedLength) => { | |
if (!Array.isArray(array)) { | |
throw new Error("expectLength expects an array"); | |
} | |
if (array.length !== expectedLength) { | |
throw new Error( | |
`Array length mismatch, got ${array.length}, expected ${expectedLength}.` | |
); | |
} | |
}; | |
// In case of non-array inputs, we should get an empty array back | |
expectLength(flattenArray({}), 0); | |
expectLength(flattenArray(""), 0); | |
// Properly flattens arrays | |
expectLength(flattenArray([[1, 2, [3]], 4]), 4); | |
expectLength(flattenArray([[1, 2, [3]], 4]), 4); | |
expectLength(flattenArray([0, [1, 2, 3, [4, [5, [6]]]]]), 7); | |
// Works with non-numbers too | |
expectLength(flattenArray([{}, null, {}, 4]), 4); | |
// Works with empty arrays | |
expectLength(flattenArray([]), 0); | |
// Expect [ 0, 1, 2, 3, 4, 5, 6, null, undefined, {} ] | |
console.log( | |
flattenArray([0, [1, 2, 3, [4, [5, [6, null, [undefined, {}, []]]]]]]) | |
); |
This file contains hidden or 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
// Takes in an array, and optionally an array of existing results, for | |
// non-array items we add them to results, for array items we call ourselves | |
// then we return our flat results array | |
export const recursiveFlatten = (array, results = []) => { | |
array.forEach(a => { | |
if (Array.isArray(a)) { | |
recursiveFlatten(a, results); | |
} else { | |
results.push(a); | |
} | |
}); | |
return results; | |
}; | |
// Will flatten an array of arbitrarily nested items into a flat | |
// array of items. e.g. [[1,2,[3]],4] -> [1,2,3,4]. | |
export const flattenArray = arrayToFlatten => { | |
if (!Array.isArray(arrayToFlatten)) { | |
return []; | |
} | |
return recursiveFlatten(arrayToFlatten); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment