Flatten _ JavaScript Interview Questions with Solutions
Flatten _ JavaScript Interview Questions with Solutions
11 // Flattens recursively.
12 flatten([1, [2, [3, [4, [5]]]]]); // [1, 2, 3, 4,
Flatten Companies
Zhenghao He
Engineering Manager, Robinhood Amazon Apple Lyft Salesforce Google
Medium 20 mins 7.05k done
Implement a function flatten that returns a newly- Coding and submission is not supported on
mobile devices. Use a wider screen to practice
created array with all sub-array elements concatenated solving this question within the editor.
recursively into a single level.
Clarification Questions
6 flatten([
7 [1, 2],
8 [3, 4],
9 ]); // [1, 2, 3, 4] 1. What type of data does the array contain? Some
10 approach only applies to certain data types.
2. How many levels of nesting can this array have? If Then, we don't want to mutate the original input array,
there are thousands-of-levels of nesting, recursion which is a good practice in general, so we will make a
might not be a good idea given its big upfront copy of the input array and return a new array with all
memory footprint. the items extracted from the input array.
3. Should we return a new array or we mutate the Here is the solution. We loop through the array with a
existing array? while loop and we take out an item from the array one at
4. Can we assume valid input, i.e. an array. Normally a time to check to see if that item is an array. If the item
the answer is "yes", so you don't have to waste your is not an array, we put it into the res array. If it is an
time doing defensive programming. array, we use a spread operator ... to get all the items
5. Does the environment the code runs on has ES6+ out of it and put them back to the array.
support? The environment determines what
methods/native APIs you have access to.
Solutions
1 type ArrayValue = any | Array<ArrayValue>;
2
3 export default function flatten(value: Array<Array
A more concise approach, compared to the previous one, 2 * @param {Array<*|Array>} value
is to use Array.prototype.some . 3
4
* @return {Array}
*/
5 export default function flatten(value) {
6 return value.reduce(
7 (acc, curr) => acc.concat(Array.isArray(curr)
1 type ArrayValue = any | Array<ArrayValue>;
8 [],
2
9 );
3 export default function flatten(value: Array<Array
10 }
4 while (value.some(Array.isArray)) {
5 value = [].concat(...value);
6 }
7
Although a recursive approach always has the risk
8
9 }
return value;
overflowing the call stack, as of this writing, in chrome,
the number of recursive calls you can make is around 10
thousands and in Firefox it is 50 thousands, so this
shouldn't be a problem in practice. However, when the
Solution 3: Recursive approach with cost of recursion becomes a concern, we can use a
Array.prototype.reduce
generator to lazily extract the flattened items from the 4 for (let i = 0; i < value.length; ) {
Solution 6: Generator
Bonus Solutions
As we have discussed earlier, if the array has a The following solutions only work under certain
thousands-of-levels nesting, a recursive approach might circumstances so they should not be used during
cause a stack overflow. We can utilize generators to yield interviews.
array item individually. As generators are lazy in nature,
this wouldn't have as big of an upfront cost as our Bonus Solution 1: Regex and
recursive approach does. JSON.stringify
1 function flattenOnlyNumbers(array) {
GFE 75 4/70 Mark complete
2 return array
3 .toString()
4 .split(',')
5 .map((numStr) => Number(numStr));
6 }
Note that this only applies when the array only contains
numbers, and this usage of toString might be thought
of as "obscure".