我们接下来介绍函数式语言中3个常见的函数:Map,Filter,Reduce。
命令式代码与声明式代码
前面我们介绍了函数式编程中常见的几种函数,下面我们要开始转变观念了。
命令式代码的意思就是,我们通过编写一条又一条指令去让计算机执行一些动作,这其中一般都会涉及到很多繁杂的细节。 而声明式就要优雅很多了,我们通过写表达式的方式来声明我们想干什么,而不是通过一步一步的指示。
// 命令式
const makes = [];
for (i = 0; i < cars.length; i++) {
makes.push(cars[i].make);
}
// 声明式
var makes = cars.map(function(car){ return car.make; });
我们看下es5 Map,Filter,Reduce函数的简单实现。
Array.prototype.map = function(f) {
const newArray = [];
const O = Object(this);
for (let i = 0; i < O.length; i++) {
newArray[i] = f(O[i]);
}
return newArray;
}
Array.prototype.filter = function(pred) {
const newArray = [];
for (var i = 0; i < this.length; ++i) {
if (pred(this[i]))
newArray[newArray.length] = this[i];
}
return newArray;
}
Array.prototype.reduce = function(f, start) {
var acc = start;
for (var i = 0; i < this.length; ++i)
acc = f(this[i], acc); // f() 接受2个参数
return acc;
};
这3个常见的函数会在我们函数式编程中经常出现的三个函数。
有一点需要说明的是,for循环是自然语言的处理结果,永远是比map快的。这个就需要你自己在编写代码的时候对利弊进行权衡。
一段函数式编程的综合应用
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.11/require.min.js"></script>
<script>
requirejs.config({
paths: {
ramda: 'https://cdnjs.cloudflare.com/ajax/libs/ramda/0.13.0/ramda.min',
jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min'
}
});
require([
'ramda',
'jquery'
],
(_, $) => {
const Impure = {
getJSON: _.curry((callback, url) => {
$.getJSON(url, callback);
}),
setHtml: _.curry((sel, html) => {
$(sel).html(html);
})
};
const img = url => $('<img />', { src: url });
const trace = _.curry((tag, x) => {
console.log(tag, x);
return x;
});
const url = t => 'https://api.flickr.com/services/feeds/photos_public.gne?tags=' + t + '&format=json&jsoncallback=?';
const mediaUrl = _.compose(_.prop('m'), _.prop('media'));
const srcs = _.compose(_.map(mediaUrl), _.prop('items'));
const images = _.compose(_.map(img), srcs);
const renderImages = _.compose(Impure.setHtml("body"), images);
const app = _.compose(Impure.getJSON(renderImages), url);
app("cats");
}
);
</script>
</head>
<body></body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。