Skip to content

Instantly share code, notes, and snippets.

@jwjames
Last active December 28, 2018 05:36
Show Gist options
  • Save jwjames/79fcbf45b40a12b87f9b4cdce6f9b40a to your computer and use it in GitHub Desktop.
Save jwjames/79fcbf45b40a12b87f9b4cdce6f9b40a to your computer and use it in GitHub Desktop.
Citrusbyte Array Flattener
/**
* A function that flattens an array that contains and infinite amount of nested arrays.
* It uses iteration over recursion because the maximum call stack size is variant,
* based on factors external from JavaScript such as which browser the code is run within.
* This will be a problem for massive arrays, probably not relevant to this code challenge,
* but I thought it was an interesting consideration.
*
* The tests can be run here: https://repl.it/@jeffcodes/Nested-Array-Flattening
*
* @param {Array} input
* @returns {Array} result
*/
function flatten(input) {
// Confirm the input argument is an array.
if (!Array.isArray(input)) {
throw new TypeError('Argument is not an Array.');
}
// Spread and reassign `input` to not affect original `input` array.
const stack = [...input];
const result = [];
while (stack.length) {
// Pop the end value from stack, assign it to `next`.
const next = stack.pop();
// If `next` is truthy and is an Array, spread out the items and push them back into `next`.
if (next && Array.isArray(next)) {
stack.push(...next);
} else if (next && Number.isInteger(next)) {
// If `next` is an integer, push it to the result array.
result.push(next);
}
}
// Reverse `result` array to restore original `input` order.
return result.reverse();
}
// Jest tests
describe('Flatten an array containing both integers and arbitrarily nested arrays of integers', () => {
it('Should return [1,2,3,4] when passed in [[1,2,[3]],4]', () => {
expect(flatten([[1,2,[3]],4])).toEqual([1,2,3,4]);
});
it('Should return [1,2,3,4,1,2,3,2,3,4] when passed in [[1,[2,3]],4,[1,2,3],[2,[3,4]]]', () => {
expect(flatten([[1,[2,3]],4,[1,2,3],[2,[3,4]]])).toEqual([1,2,3,4,1,2,3,2,3,4]);
});
it('Should return [1,2,3,4] when passed in an array with some empty values: [[1,,2,,[3]],,4]', () => {
expect(flatten([[1,,2,,[3]],,4])).toEqual([1,2,3,4]);
});
it('Should return an empty array when passed in an array of all empty values: [,,[,],,]', () => {
expect(flatten([,,[,],,])).toEqual([]);
});
it('Should return a TypeError when passed in a non-array argument', () => {
const testFlatten = () => {
flatten(undefined)
};
expect(testFlatten).toThrowError(TypeError('Argument is not an Array.'));
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment