Last active
February 10, 2018 17:58
-
-
Save joshburgess/82036f8c7aa036d04425692bae667fbd to your computer and use it in GitHub Desktop.
Solutions showing how to flatten arbitrarily nested arrays of ints in JavaScript
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
// shorthand function for the Number.isInteger method | |
const isInt = Number.isInteger | |
// shorthand function for the Array.isArray method | |
const isArray = Array.isArray | |
// functional wrapper for the Array.reduce method | |
const reduce = f => initVal => arr => arr.reduce(f, initVal) | |
// functional wrapper for the Array.concat method | |
const concat = arrA => arrB => arrA.concat(arrB) | |
// functional composition utility | |
const compose2 = (f, g) => x => f(g(x)) | |
// fairly easy to understand & explain solution using recursion & | |
// leaning on JavaScript's native reduce & concat methods | |
export const flatten = arr => !isArray(arr) | |
? [] | |
: reduce( | |
(prev, curr) => isArray(curr) | |
? compose2(concat(prev), flatten)(curr) | |
: (!isInt(curr) | |
? prev // omit non-integer values | |
: concat(prev)(curr) | |
) | |
)([])(arr) |
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
import test from 'ava' | |
import { flatten } from './flatten' | |
// import { flatten } from './flattenAlt' | |
test('nested arrays should be flattened', t => { | |
const flattened = flatten([[1, 2, [3]], 4]) | |
const expected = [1, 2, 3, 4] | |
t.deepEqual(flattened, expected) | |
}) | |
test('non-integers should be omitted', t => { | |
const flattened = flatten([[1, 2, 'C', [3, {}]], 4]) | |
const expected = [1, 2, 3, 4] | |
t.deepEqual(flattened, expected) | |
}) | |
test('flat arrays should be returned as is', t => { | |
const flattened = flatten([1, 2, 3, 4]) | |
const expected = [1, 2, 3, 4] | |
t.deepEqual(flattened, expected) | |
}) | |
test('empty arrays should be returned as is', t => { | |
const flattened = flatten([]) | |
const expected = [] | |
t.deepEqual(flattened, expected) | |
}) |
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
// shorthand function for the Number.isInteger method | |
const isInt = Number.isInteger | |
// shorthand function for the Array.isArray method | |
const isArray = Array.isArray | |
const buildArray = f => first => rest => [ | |
...isArray(first) | |
? f(first) | |
: (!isInt(first) | |
? [] // omit non-integer values | |
: [first] | |
), | |
...f(rest), | |
] | |
// somewhat harder to understand & explain solution using recursion, | |
// pattern matching/destructuring, & the rest/spread operator | |
export const flatten = ([first, ...rest]) => | |
first === undefined | |
? [] // break recursion, avoid "Max call stack size exceeded" error | |
: buildArray(flatten)(first)(rest) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FP!