Skip to content

Instantly share code, notes, and snippets.

@xkizer
Last active June 17, 2016 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xkizer/be6c976e4ca5674456468e5e73340ded to your computer and use it in GitHub Desktop.
Save xkizer/be6c976e4ca5674456468e5e73340ded to your computer and use it in GitHub Desktop.
'use strict';
/**
* Flattens a deep-nested array of integers (numbers)
* @param {Number[]} inpArray A possibly deep-nested array of numbers.
* The level of nesting is limited by the maximum stack size of the
* JavaScript engine (the lowest we have seen is IE6 at 1130)
* @return {Number[]} Returns a flattened version of the input array
*/
function flatten (inpArray) {
const outputArray = [];
// We will do this optimistically, and catch any errors.
try {
inpArray.forEach(item => {
if (typeof item === 'number') {
// Push this item to the output array and move to the next item
outputArray.push(item);
return;
}
// This is not a number. We assume it's an array
// We will attempt to flatten the array recursively, optimistically
const flt = flatten(item);
flt.forEach(innerItem => {
outputArray.push(innerItem);
});
});
} catch (e) {
throw new Error('Supplied parameter is not a nested array of numbers');
}
return outputArray;
}
module.exports = flatten;
'use strict';
// This test makes use of mocha+chai. It is assumed you have installed mocha and chai through npm. Use BDD.
const chai = require('chai');
const expect = chai.expect;
const flatten = require('./array.flatten.js');
describe('flatten', () => {
const testFn = (...args) => () => { flatten.apply(null, args); };
it('requires first parameter to be an array', () => {
expect(testFn()).to.throw(Error);
expect(testFn(1)).to.throw(Error);
expect(testFn(29.34)).to.throw(Error);
expect(testFn('a string')).to.throw(Error);
expect(testFn(null)).to.throw(Error);
expect(testFn(undefined)).to.throw(Error);
expect(testFn({})).to.throw(Error);
expect(testFn(NaN)).to.throw(Error);
expect(testFn(true)).to.throw(Error);
expect(testFn(new Date())).to.throw(Error);
expect(testFn(4, [1, 2, 3])).to.throw(Error);
expect(testFn([1, 2, 3])).to.not.throw(Error);
expect(testFn([1, 2, 3], 'additional parameter')).to.not.throw(Error);
});
it('requires the provided array to contain only numbers', () => {
expect(testFn([1, 2, 3, 'a'])).to.throw(Error);
expect(testFn([1, 2, 3, 'b', 'a'])).to.throw(Error);
expect(testFn(['string'])).to.throw(Error);
expect(testFn([true])).to.throw(Error);
expect(testFn([[1, 2, 3, 4], ['a', 'string']])).to.throw(Error);
expect(testFn([1, 2, 3, [6, ['a']]])).to.throw(Error);
expect(testFn([1, 2, 3, undefined])).to.throw(Error);
expect(testFn([1, 2, 3, null])).to.throw(Error);
expect(testFn([1, 2, 3, NaN])).to.not.throw(Error);
expect(testFn([1, 2, 3, {}])).to.throw(Error);
expect(testFn([1, 2, 3, {forEach: ''}])).to.throw(Error);
expect(testFn([1, 2, 3, /a-z/])).to.throw(Error);
});
it('returns expected values', () => {
expect(flatten([1, 2, 3])).to.eql([1, 2, 3]);
expect(flatten([1, 2, 3, 1])).to.eql([1, 2, 3, 1]);
expect(flatten([1, [2], 3])).to.eql([1, 2, 3]);
expect(flatten([1, 2, 3.9])).to.eql([1, 2, 3.9]);
expect(flatten([1, [2, 3]])).to.eql([1, 2, 3]);
expect(flatten([[1,2,[3]],4])).to.eql([1, 2, 3, 4]);
expect(flatten([[1,2,[3]],4, [5, [6], [7, [8], [9]]]])).to.eql([1, 2, 3, 4, 5, 6, 7, 8, 9]);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment