Skip to main content

Multiple Instruction Arrow Functions in ES6

Cross post from my employer's development blog:

Recently, I had a bit of JavaScript code that was a small series of map and reduce functions. To keep things nice and tight, I of course wanted to use single line arrow functions as much as possible. Implicit returns, no brackets, no ‘function’ syntax. I had one reduce() call though where my logic was this:

arr.reduce((list2, b) => {
         if (list2.indexOf(b) === -1){
         return list2;
       }, []);

High level: only add item b from array arr to a new array if it doesn’t already exist in the new array. Simple duplicate removal for the original array. This works, and is probably the easiest to understand, but doesn’t make for the best grouping along with other calls on the same array. How could I modify this a bit so that I could use a bracketless arrow function with an implicit return?

arr.reduce((list2, b) =>
         ((list2.indexOf(b) === -1 && list2.push(b)) || 1) && list2
       , []);

This is certainly shorter in terms of vertical space, and a bit less code overall. However, it’s not very straight-forward to read. The logical AND operator ensures push() is only called on list2 if the item ‘b’ is not found in list2. In the case that ‘b’ is indeed in list2, the value’s index will not be -1 and the AND expression will short circuit and return false. Which would return false for the whole function, which we don’t want. So, I use the logical OR operator and 1 to ensure we get a truthy return value and then another AND to force list2 to be returned.

During all this, I was reminded of part of the JS spec about the comma operator. According to [MDN][comma]:

“The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.”

Nice! We can simplify this even more:

arr.reduce((list2, b) =>
         (list2.indexOf(b) === -1 && list2.push(b), list2)
       , []);

Which transpiles in ES5 to:

arr.reduce(function (list2, b) {
         return list2.indexOf(b) === -1 && list2.push(b), list2;
}, []);

We’ve removed two of the three logical operators and one of the parens wrappings. Overall, I’d say it’s cleaner than the 2nd iteration and preferable to it as well. However, the use of the comma operator like this is probably not immediately known to the random developer reading the code. Thus I’m a tad hesitant moving forward with it and may go with the more verbose, but easier to understand, bracketed arrow function. Neat trick though, especially as you can chain more commas and expressions to your heart’s desire.



Popular posts from this blog

Changing Password Requirements with SailsJS and Passport

Cross post from my employer's development blog: If you perform an installation of [Passport][passport] with [SailsJS][sails] using the [Sails Passport Auth Generator][sails-generate-auth] you get several files in your app already configured for you. If you then use passport-local, you will already have a complexity requirement on the password. It defaults to requiring 8 characters minimum, letters, numbers, and symbols. What if you want to change this requirement? In the generated model file `Passport.js`, you should see a line that says `provider   : { type: 'alphanumericdashed' },` and `password    : { type: 'string', minLength: 6 }`. The minLength is an easy and obvious change. What about the complexity requirement though? This stumped me for a bit. There doesn’t seem to be any mention of these keywords or providers on the Passport official site, nor anything in the [Passport-local repository][pass

Fancy FTP Deployment with Grunt

I recently dove into Grunt.js at work for automating our build process and I haven’t looked back. It’s an awesome tool with a plug-in for just about anything. I expected the usual would be there like JavaScript minification and concatenation, but I was surprised at a few others that I found, one being for FTP file deployment. Just shows how popular and community supported Grunt is. There are a few FTP plug-ins available for Grunt. I didn’t do an analysis of all of them but ran across grunt-ftp-push which seemed to do what I needed so I decided to try it out. A simple ftp-push setup to upload an entire project via FTP could look like this: grunt . initConfig ({ ftp_push : { all : { options : { host : '' , port : 21 , dest : '/project/path/' , username : 'user' , password : 'pass' }, expand : true , cwd : 'dist' , src : [ '**/*' ,

Atari E3 2004 PAL digital press kit

Making note of some old swag. The Atari E3 2004 PAL digital press kit. See video for details.