函数式编程示例
问题描述:
这是为了理解函数式编程。函数式编程示例
它来自一篇关于嫌杂志: http://www.smashingmagazine.com/2014/07/dont-be-scared-of-functional-programming/
嗨,我有以下数据
var data = [
{
name: "Jamestown",
population: 2047,
temperatures: [-34, 67, 101, 87]
},
{
name: "Awesome Town",
population: 3568,
temperatures: [-3, 4, 9, 12]
}
{
name: "Funky Town",
population: 1000000,
temperatures: [75, 75, 75, 75, 75]
}
];
我需要在一个新的数组
平均气温和平均人口和商店[
[average temperature, average population]
]
我想解决这个问题的方法是使用两个for循环。为什么这是解决问题的不好方法?为什么函数式编程是答案?
答
我想解决这个问题的方法是使用两个for循环。
命令式编程没有错。许多人喜欢用这种方式编写代码,而且对他们来说感觉很自然。但是,为什么不利用函数式编程的一些好处。
为什么这是解决问题的不好方法?
如上所述,它不一定解决问题,但是,让我们来看看他们使用的示例代码,一个糟糕的方式:
var coords = [],
totalTemperature = 0,
averageTemperature = 0;
for (var i=0; i < data.length; i++) {
totalTemperature = 0;
for (var j=0; j < data[i].temperatures.length; j++) {
totalTemperature += data[i].temperatures[j];
}
averageTemperature = totalTemperature/data[i].temperatures.length;
coords.push([averageTemperature, data[i].population]);
}
它解决了这个问题。现在,这里是一个功能更强大的方式相同的片段:
function average(sum, count) {
return sum/count;
}
function sum(x, y) {
return x + y;
}
var coords = data.map(function(item) {
return [
average(item.temperatures.reduce(sum), item.temperatures.length),
item.population
];
});
显然,作为@Fabio指出它可以更进一步采取但是,我想用相同的逻辑来告诉你一个简单的例子。
你觉得哪些比较容易推理,测试等?
为什么函数式编程的答案是?
函数式编程并不是JavaScript语言的一些灵丹妙药,但JavaScript的美妙之处在于我们可以利用其他语言的范例。
答
这里有一个(在许多方面做它)。当然,如average
reducer而不是sum
这样的更专用的reduce函数会增加代码的可读性,我认为这个版本在第一次迭代时更容易“自行提出”,然后可以进行细化。
function sum(a,b){return a+b;}
function flatten(a,b){return a.concat(b);}
console.log([
data.map(function(datum){
return datum.temperatures;
}).reduce(flatten,[]).reduce(sum,0)
/data.map(function(datum){
return datum.temperatures;
}).reduce(flatten,[]).length
,
data.map(function(datum){
return datum.population;
}).reduce(sum,0)
/data.length
])
现在,这里的一个更可读的,但稍硬versionn写:
function total(running,x){return {sum:running.sum+x, count:running.count+1};}
function average(o){return o.sum/o.count;}
function flatten(a,b){return a.concat(b);}
function property(name){return function(x){return x[name];}}
var startingTotal={sum:0,count:0};
[
average(data.map(property("temperatures")).reduce(flatten).reduce(total,startingTotal)),
average(data.map(property("population")).reduce(total,startingTotal))
]
检查编辑 – Jasmine
该杂志不应该解释为什么他们认为函数式编程是“答案”吗? – crush