![](/img/trans.png)
[英]What is a good example for functional style web programming using javascript?
[英]Functional programming example
這是為了了解函數式編程。
它來自打擊雜志上的文章: 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的優點在於我們可以利用其他語言的范例。
這是一個(在許多方法中)。 當然,更專業的reduce函數(例如average
reducer而不是sum
將提高代碼的可讀性,我認為此版本在第一次迭代時更容易“自行提出”,然后可以進行完善。
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
])
現在這是一個更具可讀性的版本,但是寫起來有點困難:
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))
]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.