Created
July 10, 2017 11:14
-
-
Save thirdknife/71cd5a88b0d7e2e22911ee58b8cf4cc6 to your computer and use it in GitHub Desktop.
Functional JavaScript Examples
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
// - Example 1.1 | |
const getServerStuff = function (callback) { | |
return ajaxCall(function (json) { | |
return callback(json); | |
}); | |
}; | |
const getServerStuff = function (callback) { | |
return ajaxCall(callback); | |
}; | |
const getServerStuff = ajaxCall; | |
getServerStuff(callback); | |
httpGet(callback); | |
// Example 1.2 | |
var BlogController = (function() { | |
var index = function(posts) { | |
return Views.index(posts); | |
}; | |
var show = function(post) { | |
return Views.show(post); | |
}; | |
var create = function(attrs) { | |
return Db.create(attrs); | |
}; | |
var update = function(post, attrs) { | |
return Db.update(post, attrs); | |
}; | |
var destroy = function(post) { | |
return Db.destroy(post); | |
}; | |
return { | |
index: index, | |
show: show, | |
create: create, | |
update: update, | |
destroy: destroy, | |
}; | |
})(); | |
var BlogController = { | |
index: Views.index.bind(Views), | |
show: Views.show, | |
create: Db.create, | |
update: Db.update, | |
destroy: Db.destroy, | |
}; | |
// Example 1.3 | |
function findUserById(users, id) { | |
const len = users.length; | |
for (let i = 0; i < len; ++i) { | |
if (users[i].id === id) return i; | |
} | |
return -1; | |
} | |
function findMessageById(messages, id) { | |
const len = messages.length; | |
for (let i = 0; i < len; ++i) { | |
if (messages[i].id === id) return i; | |
} | |
return -1; | |
} | |
// Example 1.3 continued... | |
function findIndexById(arr, id) { | |
const len = arr.length; | |
for (let i = 0; i < len; ++i) { | |
if (arr[i].id === id) return i; | |
} | |
return -1; | |
} | |
// Example 1.3 continued... | |
function findIndex(predicate, arr, val) { | |
const len = arr.length; | |
for (let i = 0; i < len; ++i) { | |
if (predicate(arr[i], val)) return i; | |
} | |
return -1; | |
} | |
// find index by id | |
findIndex((a, b) => a.id === b.id, arr, 123); | |
// find index by some nested property | |
findIndex((a, b) => a.nested.prop === b.nested.prop, arr, 'some val'); | |
// behaves like indexOf | |
findIndex((a, b) => a === b, arr, 'User'); | |
// Example 2.1 | |
var xs = [1, 2, 3, 4, 5]; | |
// pure | |
xs.slice(0, 3); | |
//=> [1, 2, 3] | |
xs.slice(0, 3); | |
//=> [1, 2, 3] | |
xs.slice(0, 3); | |
//=> [1, 2, 3] | |
// impure | |
xs.splice(0, 3); | |
//=> [1, 2, 3] | |
xs.splice(0, 3); | |
//=> [4, 5] | |
xs.splice(0, 3); | |
//=> [] | |
// Example 2.2 | |
// impure | |
let minimum = 21; | |
const checkAge = function (age) { | |
return age >= minimum; | |
}; | |
// pure | |
const checkAge = function (age) { | |
const minimum = 21; | |
return age >= minimum; | |
}; | |
// Example 2.3 | |
const findObjectByKey = (arr, key, val) => arr.filter(d => d[key] === val)[0]; | |
const markRecipientAsRead = (userId, msg) => { | |
msg.recipientStatus[userId] = 'read'; | |
return msg; | |
}; | |
const markMessageAsRead = (msgs, msgId, userId) => { | |
const msg = findObjectByKey(msgs, 'id', msgId); | |
return markRecipientAsRead(userId, msg); // not pure, mutating state | |
}; | |
const curry = _.curry; | |
// Example 3.1 | |
const match = curry((what, str) => str.match(what)); | |
const hasSpaces = match(/\s+/g); | |
hasSpaces('Hello World'); // [' '] | |
hasSpaces('HelloWorld'); // null | |
// Example 3.2 | |
const findActiveUsers = users => { | |
const found = []; | |
for (let i = 0; users[i]; ++i) { | |
const u = users[i]; | |
if (u.active) found.push(u); | |
} | |
return found; | |
}; | |
const findActiveUsers = users => { | |
return users.filter(u => u.active); | |
}; | |
const filter = curry((iteratee, arr) => arr.filter(iteratee)); | |
const findActiveUsers = filter(u => u.active); | |
findActiveUsers(users) // returns array of active users | |
// Example 3.3 | |
const transformUsers = users => { | |
return users.map(u => { | |
return { | |
id: u.id, | |
firstName: u.first_name, | |
lastName: u.last_name, | |
// ... | |
}; | |
}); | |
}; | |
const map = curry((iteratee, arr) => arr.map(iteratee)); | |
const transformUser = u => { | |
return { | |
id: u.id, | |
firstName: u.first_name, | |
lastName: u.last_name, | |
// ... | |
}; | |
}; | |
const transformUsers = map(transformUser); | |
// Example 4.1 | |
const first = arr => arr[0]; | |
const reverse = arr => { | |
let i = arr.length; | |
const rev = []; | |
while (--i) rev.push(arr[i]); | |
return rev; | |
}; | |
const last = arr => { | |
const rev = reverse(arr); | |
return first(rev); | |
}; | |
// Let's rewrite in functional way ::.. | |
const first = _.first; | |
const reverse = arr => _.reduceRight(arr, (rev, d) => rev.concat(d), []); | |
const last = arr => { | |
const rev = reverse(arr); | |
return first(rev); | |
}; | |
// Let's make it point free | |
const first = _.first; | |
const reduceRight = _.curry((iteratee, initVal, arr) => _.reduceRight(arr, iteratee, initVal)); | |
const reverse = reduceRight((rev, d) => rev.concat(d), []); | |
const last = _.flow([reverse, first]); | |
res = last(arr); | |
// Example 4.2 | |
const user = { | |
fname: 'First', | |
lname: 'Last', | |
// ... | |
}; | |
const join = curry((sep, arr) => arr.join(sep)); | |
const initials = _.flow([ | |
user => [user.fname, user.lname], | |
_.compact, | |
map(_.first), | |
join('') | |
]); | |
const userInitials = initials(user); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment