组合多个函数
function compose() {
var args = arguments;
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
}
}
var toUpperCase = function(x) { return x.toUpperCase(); }
var hello = function(x) { return 'HELLO, ' + x; }
var greet = compose(hello, toUpperCase);
greet('kevin')
函数无须提及将要操作的数据是什么样的
var data = {
result: "SUCCESS",
tasks: [
{id: 104, complete: false, priority: "high",
dueDate: "2013-11-29", username: "Scott",
title: "Do something", created: "9/22/2013"},
{id: 105, complete: false, priority: "medium",
dueDate: "2013-11-22", username: "Lena",
title: "Do something else", created: "9/22/2013"},
{id: 107, complete: true, priority: "high",
dueDate: "2013-11-22", username: "Mike",
title: "Fix the foo", created: "9/22/2013"},
{id: 108, complete: false, priority: "low",
dueDate: "2013-11-15", username: "Punam",
title: "Adjust the bar", created: "9/25/2013"},
{id: 110, complete: false, priority: "medium",
dueDate: "2013-11-15", username: "Scott",
title: "Rename everything", created: "10/2/2013"},
{id: 112, complete: true, priority: "high",
dueDate: "2013-11-27", username: "Lena",
title: "Alter all quuxes", created: "10/5/2013"}
]
};
// 过滤Scott未完成的任务
// [
// {id: 110, title: "Rename everything", dueDate: "2013-11-15", priority: "medium"},
// {id: 104, title: "Do something", dueDate: "2013-11-29", priority: "high"}
// ]
// 第一版 过程式编程
var fetchData = function() {
// 模拟
return Promise.resolve(data)
};
var getIncompleteTaskSummaries = function(membername) {
return fetchData()
.then(function(data) {
return data.tasks;
})
.then(function(tasks) {
return tasks.filter(function(task) {
return task.username == membername
})
})
.then(function(tasks) {
return tasks.filter(function(task) {
return !task.complete
})
})
.then(function(tasks) {
return tasks.map(function(task) {
return {
id: task.id,
dueDate: task.dueDate,
title: task.title,
priority: task.priority
}
})
})
.then(function(tasks) {
return tasks.sort(function(first, second) {
var a = first.dueDate,
b = second.dueDate;
return a < b ? -1 : a > b ? 1 : 0;
});
})
.then(function(task) {
console.log(task)
})
};
getIncompleteTaskSummaries('Scott')
// 第二版 pointfree 改写
var fetchData = function() {
return Promise.resolve(data)
};
// 编写基本函数
var prop = curry(function(name, obj) {
return obj[name];
});
var propEq = curry(function(name, val, obj) {
return obj[name] === val;
});
var filter = curry(function(fn, arr) {
return arr.filter(fn)
});
var map = curry(function(fn, arr) {
return arr.map(fn)
});
var pick = curry(function(args, obj){
var result = {};
for (var i = 0; i < args.length; i++) {
result[args[i]] = obj[args[i]]
}
return result;
});
var sortBy = curry(function(fn, arr) {
return arr.sort(function(a, b){
var a = fn(a),
b = fn(b);
return a < b ? -1 : a > b ? 1 : 0;
})
});
var getIncompleteTaskSummaries = function(membername) {
return fetchData()
.then(prop('tasks'))
.then(filter(propEq('username', membername)))
.then(filter(propEq('complete', false)))
.then(map(pick(['id', 'dueDate', 'title', 'priority'])))
.then(sortBy(prop('dueDate')))
.then(console.log)
};
getIncompleteTaskSummaries('Scott')
// 第四版 使用 compose
var fetchData = function() {
return Promise.resolve(data)
};
var getIncompleteTaskSummaries = function(membername) {
return fetchData()
.then(R.compose(
console.log,
R.sortBy(R.prop('dueDate')),
R.map(R.pick(['id', 'dueDate', 'title', 'priority'])
),
R.filter(R.propEq('complete', false)),
R.filter(R.propEq('username', membername)),
R.prop('tasks'),
))
};
getIncompleteTaskSummaries('Scott')
// 第三版 使用 ramda.js
var fetchData = function() {
return Promise.resolve(data)
};
var getIncompleteTaskSummaries = function(membername) {
return fetchData()
.then(R.prop('tasks'))
.then(R.filter(R.propEq('username', membername)))
.then(R.filter(R.propEq('complete', false)))
.then(R.map(R.pick(['id', 'dueDate', 'title', 'priority'])))
.then(R.sortBy(R.prop('dueDate')))
.then(console.log)
};
getIncompleteTaskSummaries('Scott')