Re #1: Rubocop calls them "guard clauses" and I tend to prefer that style as well.
But if there are only two branches, I sometimes prefer the symmetry of if / else. Especially when if is an expression (as it is in Ruby).
if / else
Either way, IMO it's usually clear enough when input validation is being done, however it gets written. It's one of those places where obscuring the intent takes real talent :P
Re: #2: agree with @nepeckman
that putting the switch statement in a function is usually a good option. Especially if multiple cases map to the same output value, because there you can use switch fallthrough to "stack" the tests and avoid repeating yourself.
Re: #3: reduce (fold) is so powerful 😍... map and filter can both be written in terms of it, and many more things as well. Many "indexed" loops can be translated into a function folded over a range of integers.
Also, I haven't seen it formalized, but it seems like a lot of tail-recursive code can be translated to "reducer style" as well -- it's a good option if the inputs can be easily generated as some sort of collection.
If the fold implementation allows early termination (a la Clojure's reduced, it becomes even more useful.
Oh yeah, in case you haven't seen it in action, you might be interested to know that a side-effect-free series of map calls can be refactored similar to your #3. map distributes across function composition, so
map(g, map(f, coll)) == map(compose(g, f), coll)
The latter form only walks the collection once, obviously. You can compose the functions manually or borrow compose from a library like Ramda.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.