Nick Scialli • August 24, 2019 • 🚀 1 minute read

If you're enjoying this blog, please consider one or both of the following:

This is a short post about a popular pattern that has been emerging recently: using the Array reduce method and spread operator ( ... ) together. Let’s look at a quick example where we use them together to swap the keys and values of an object.

const obj = { a : 1 , b : 2 , c : 3 } ; const flipped = Object . entries ( obj ) . reduce ( ( all , [ key , val ] ) => ( { ... all , [ val ] : key , } ) , { } ) ; console . log ( flipped ) ;

Pretty cool, right?

The Problem: Using Reduce and Spread Together Can Be Pretty Inefficient for Large Arrays

If you study the example above, you’ll realize that we’re creating a shallow copy of our all object each time we execute the function being passed to the reduce method. This may not be a big deal for small arrays, but can quickly become a performance bottleneck. Let’s create a really large array and test how our reduce/spread combination performs.

const largeArr = new Array ( 100000 ) . fill ( 1 ) . map ( ( _ , i ) => i ) ; console . time ( 'try 1' ) ; const obj1 = largeArr . reduce ( ( all , el ) => ( { ... all , [ el ] : el , } ) , { } ) ; console . timeEnd ( 'try 1' ) ;

Yikes, that took 21 seconds! So what are we to do?

Plain Old Loops to the Rescue

In a lot of cases, it turns out that a plain old for loop or forEach method will be sufficient for the task. In the following example, we accomplish the same task as the above code in only ~5 milliseconds.

console . time ( 'try 2' ) ; const obj2 = { } ; for ( let i = 0 ; i < largeArr . length ; i ++ ) { obj2 [ largeArr [ i ] ] = largeArr [ i ] ; } console . timeEnd ( 'try 2' ) ;

Conclusion