Created
August 3, 2022 20:38
-
-
Save jfet97/246bc525f33f00e6ac65c101625f5e42 to your computer and use it in GitHub Desktop.
Recursive, tail-recursive and iterative versions of flatten
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
{ | |
function flatten_it(a) { | |
let res = [...a] | |
while (res.some(el => Array.isArray(el))) { | |
for (let i = 0; i < res.length; i++) { | |
if (Array.isArray(res[i])) { | |
res.splice(i, 1, ...res[i]) | |
} | |
} | |
} | |
return res | |
} | |
function flatten_it2(a) { | |
let array = a | |
let toBeFlattened = [] | |
let res = [] | |
while (array.length !== 0 || toBeFlattened.length !== 0) { | |
if (array.length !== 0) { | |
const [first, ...rest] = array | |
if (Array.isArray(first)) { | |
array = first | |
toBeFlattened = [...rest, ...toBeFlattened] | |
} else { | |
array = rest | |
res = [...res, first] | |
} | |
} else { | |
array = toBeFlattened | |
toBeFlattened = [] | |
} | |
} | |
return res | |
} | |
flatten_it2([ | |
[ | |
[ | |
[ | |
[ | |
[ | |
[1] | |
] | |
] | |
], 2, 3, [[[4, [[[[5]]]]]]] | |
] | |
] | |
]) | |
// const RES = flatten_it([[], ["a", "b"] ,[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [4], [[[[[[[[[563]]]]]]]]]]) | |
// console.log({ RES }) | |
} | |
// let's pretend we haven't the flatMap method nor the flat one | |
function flatten(array) { | |
const toRet = [] | |
for (const el of array) { | |
if (Array.isArray(el)) { | |
toRet.push(...flatten(el)) | |
} else { | |
toRet.push(el) | |
} | |
} | |
return toRet | |
} | |
function flatten2(array, toBeFlatten = [], res = []) { | |
if (array.length === 0) { | |
if (toBeFlatten.length === 0) { | |
return res | |
} else { | |
return flatten2(toBeFlatten, [], res) | |
} | |
} else { | |
const [first, ...rest] = array | |
if (Array.isArray(first)) { | |
return flatten2(first, [...rest, ...toBeFlatten], res) | |
} else { | |
return flatten2(rest, toBeFlatten, [...res, first]) | |
} | |
} | |
} | |
function flatten3(array, toBeFlattened = [], res = []) { | |
let nextArray = [] | |
let nextToBeFlattened = [] | |
let nextRes = [] | |
const isArrayEmpty = array.length === 0 | |
const isToBeFlattenEmpty = toBeFlattened.length === 0 | |
// the main array is now empty but something is pending, waiting to be flattened | |
if (isArrayEmpty && !isToBeFlattenEmpty) { | |
nextArray = toBeFlattened | |
nextToBeFlattened = [] | |
nextRes = res | |
} | |
// there are still elements inside the main array | |
if (!isArrayEmpty) { | |
const [first, ...rest] = array | |
const isFirstElArray = Array.isArray(first) | |
// the first element of the main array is an array itself | |
if (isFirstElArray) { | |
// we do recur on the first element, the rest of the main array | |
// we'll be handled later | |
nextArray = first | |
nextToBeFlattened = [...rest, ...toBeFlattened] | |
nextRes = res | |
} else { | |
// the first element of the main array isn't an array: | |
// we can add it to the accumulator (res), to then handle the | |
// rest of the main array | |
nextArray = rest | |
nextToBeFlattened = toBeFlattened | |
nextRes = [...res, first] | |
} | |
} | |
// base case: both the main array and the "pending" one are empty | |
if (isArrayEmpty && isToBeFlattenEmpty) { | |
return res | |
} else { | |
return flatten3(nextArray, nextToBeFlattened, nextRes) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment