Reputation: 8685
This is to understand functional programming.
It comes from the the article on smacking magazine: http://www.smashingmagazine.com/2014/07/dont-be-scared-of-functional-programming/
Hi I have the following data
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]
}
];
I need to get the average temperature and average population and store in a new array
[
[average temperature, average population]
]
The way I was thinking of solving this problem is using two for loops. Why is that a bad way to solve the problem? Why is functional programming the answer?
Upvotes: 0
Views: 155
Reputation: 3097
The way I was thinking of solving this problem is using two for loops.
There is nothing wrong with imperative programming. Many people prefer to write code this way and to them it feels natural. However, why not leverage some of the benefits of functional programming.
Why is that a bad way to solve the problem?
As stated above, it isn't necessarily a bad way to solve the problem but, let's have a look at the example code they used:
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]);
}
It solves the problem. Now here is the same snippet in a more functional way:
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
];
});
Obviously, as @Fabio has pointed out it can be taken much further but, I wanted to show you a simpler example using the same logic.
Which do you find easier to reason with, test, etc...?
Why is functional programming the answer?
Functional programming isn't some silver bullet for the JavaScript language but, the beauty of JavaScript is that we can leverage paradigms from other languages.
Upvotes: 2
Reputation: 2511
Here's one (among many ways of doing it). Of course, a more specialized reduce function like average
reducer instead of sum
would increase the readability of the code, I think this version is easier to "come up with on your own" on the first iteration, and could then be refined.
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
])
Now here's a more readable, but slightly harder to write 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))
]
Upvotes: 1