Skip to content

Instantly share code, notes, and snippets.

@jfet97
Created August 3, 2022 20:38
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 jfet97/246bc525f33f00e6ac65c101625f5e42 to your computer and use it in GitHub Desktop.
Save jfet97/246bc525f33f00e6ac65c101625f5e42 to your computer and use it in GitHub Desktop.
Recursive, tail-recursive and iterative versions of flatten
{
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