# Learn by Doing Lodash _.flatten & company

`_.flatten(array)`

Flattens `array` a single level deep.

`_.flattenDeep(array)`

Recursively flattens `array`.

`_.flattenDepth(array, [depth=1])`

Recursively flatten `array` up to `depth` times.

See the full documentation for these methods here.

The first time I froze my browser trying to run a script with an incorrectly structured recursive function, it felt like I had broken the world. Since then I’ve tended to shy away from them: it just feels wrong to call a function within itself. But`_.flattenDeep` forces me to utilise recursion, and `_.flattenDepth` makes it especially important that I understand exactly how and why it works.

### Flatten

`_.flatten` is pretty straightforward: just push each value in the array to the new result array. O(n) — in fact, all the following methods should also be O(n) depending upon your definition of the input.

Since we’re technically flattening a single layer deep, we only have to evaluate the inner arrays once; we don’t care what they contain as long as we can copy it.

### FlattenDeep

`_.flattenDeep` is almost the same as `_.flatten`, but we start playing with recursion. We do care what’s inside the inner arrays, since we want our final result to be totally ‘flat’. If we hit an array within an array, we pass the flatten() function again… which will run again if we hit another array within the array we’re evaluating… which will run again if we hit another array within that array…

Ultimately, it just grabs everything and pushes it into our result array. Exactly as we want.

### FlattenDepth

`_.flattenDepth` cares about how many arrays we’ve seen during the evaluation, but when we’re dealing with a recursive function how do we keep a counter? Honestly, I struggled here: I kept worrying about the internal scope of each new flatten. You think the solution at this point would be obvious, but it took a couple of tries for me to realise that I needed to move the counter outside the function altogether.

The log statements in the CodePen below might help if you don’t understand why this works.

Overall, I feel a little more comfortable using recursion after trying to replicate this method. Admittedly it took longer than I’d like, but next time I run into an problem requiring a recursive function I’ll be a little faster.

But! Did you notice something ugly in the `_.flattenDepth` code?

`depth = depth === undefined ? 1 : Math.floor(depth);if (l === 0 || Number.isNaN(depth)) { return arr;}`

I’ve been running into weird results from Lodash while running my test cases. I make it a point to pass in unexpected arguments in my tests, and passing an `array`, `string`, or `null` for depth causes `_.flattenDepth` to return the original array. An `undefined` depth defaults to 1, but if you pass a decimal it will run it through a function which I’m roughly equating to `Math.floor`.

While this is most likely done to keep Lodash fairly user-friendly, I’m still debating on the value of these weird edge cases. You can see all my test cases in the GitHub repo here.