簡體   English   中英

功能編程示例

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM