Last active
February 28, 2016 12:32
-
-
Save RebootJeff/d8877fdbcff79ec140cf to your computer and use it in GitHub Desktop.
Beginner-friendly example of refactoring JavaScript to functional programming style
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See this blog post for full explanation: | |
// https://rebootjeff.github.io/blog/2015/12/11/example-refactoring-to-functional-js-combine-keyed-lists/ | |
// Dependencies | |
var _ = require('lodash'); | |
var R = require('ramda'); | |
// Example input | |
var usersBySocialNetwork = { | |
twitter: [ | |
{ name: '@RebootJeff' }, | |
{ name: '@doitwithalambda' }, | |
null | |
], | |
facebook: [ | |
null, | |
{ name: 'Kevin' }, | |
{ name: 'Bianca' }, | |
] | |
}; | |
// Expected output | |
var users = [ | |
{ name: '@RebootJeff' }, | |
{ name: '@doitwithalambda' }, | |
{ name: 'Kevin' }, | |
{ name: 'Bianca' } | |
]; | |
// Original Solution | |
function combineKeyedArrays_v1(keyedArrays){ | |
var flattened = []; | |
// produce a flat Array from an Object with values that are arrays | |
_.each(keyedArrays, function(array){ | |
flattened = flattened.concat(array); | |
}); | |
// only return the truthy elements of flat Array | |
return _.filter(flattened, function(element) { | |
return Boolean(element); | |
}); | |
} | |
// Refactored using Lodash's Chain | |
function combineKeyedArrays_v2(keyedArrays){ | |
return _.chain(keyedArrays) | |
.reduce(concatArray, []) | |
.filter(Boolean) | |
.value(); | |
} | |
function concatArray(arr, val) { | |
return arr.concat(val); | |
} | |
// Refactored using Lodash's function composition | |
var combineKeyedArrays_v3 = _.flow( | |
_.values, | |
_.flatten, | |
_.compact | |
); | |
// Refactored using Ramda's function composition and currying | |
var combineKeyedArrays_v4 = R.pipe( | |
R.values, | |
R.unnest, | |
R.filter(Boolean) | |
); | |
// Possible type signatures for documentation purposes: | |
// Object<Array> --> Array (more old-fashioned) | |
// ...or...maybe... | |
// {k: [v]} --> [v] (similar to Ramda docs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment