Example analysis of javascript functional programming

• 2020-06-01 08:21:55
• OfStack

This article illustrates functional programming with javascript as an example. Share with you for your reference. The specific analysis is as follows:

js, like other dynamic languages 1, can write higher-order functions, which are functions that manipulate functions. Because in js a function is a thorough object, a class 1 citizen, this provides a prerequisite for functional programming.

Here is a sample code from an js tutorial that calculates the average and standard deviation of array elements. First, list 1 ways to write non-functional programming:

``````
var data = [1,1,3,5,5];
var total = 0;
for(var i = 0;i < data.length;i++)
total += data[i];
var mean = tatal/data.length; // The mean for 3
// Calculation standard deviation
total = 0;
for(var i = 0;i < data.length;i++){
var deviation = data[i] - mean;
tatal += deviation * deviation;
}
var stddev = Math,.sqrt(total/(data.length-1));// The standard deviation for 2``````

To use functional programming, we define some help functions in advance (helper functions):

``````
// Converts a class array object into a real array
function array(a,n){
return Array.prototype.slice.call(a,n||0);
}
// Pass the function arguments to the left
function partial_left(f){
var args = arguments;
return function(){
var a = array(args,1);
a = a.concat(array(arguments));
return f.apply(this,a);
};
}
// Pass the arguments of the function to the right
function partial_right(f){
var args = arguments;
return function(){
var a = array(arguments);
a = a.concat(array(args,1));
return f.apply(this,a);
};
}
// The function argument is used as a template,
// In the argument list undefined The value is filled with the actual argument value.
function partial(f){
var args = arguments;
return function(){
var a = array(args,1);
var i = 0,j = 0;
for(;i<a.length;i++)
if(a[i] === undefined)
a[i] = arguments[j++];
a = a.concat(array(arguments,j));
return f.apply(this,a);
};
}
// return 1 The functions are similar to f(g())
function compose(f,g){
return function(){
return f.call(this,g.apply(this,arguments));
};
}``````

Here's the js code that is fully functional:

``````
var data = [1,1,3,5,5];
var sum = function(x,y){return x+y;};
var product = function(x,y){return x*y;};
var neg = partial(product,-1);
var square = partial(Math.pow,undefined,2);
var sqrt = partial(Math.pow,undefined,0.5);
var reciprocal = partial(Math.pow,undefined,-1);
// All right, orgasm bird  :)
var mean = product(reduce(data,sum),reciprocal(data.length));
var stddev = sqrt(product(reduce(map(data,compose(square,partial(sum,neg(mean)))),sum),reciprocal(sum(data.length,-1))));``````

Except for the reduce and map functions, all other functions are given. The reduce function is similar to the inject function in ruby:

``````
ary = (1..10).to_a
ary.inject(0) {|sum,i|sum + i} // The results for 55``````

js is written as follows:

``````
var ary = [1,2,3,4,5,6,7,8,9,10]
ary.reduce(function(sum,i){
return sum + i;
},0);``````

0 is the initial value of sum. If omitted, sum is the value of the first element of the array, which can be omitted here.

The map function is also very simple. It is similar to operating on each element of an array and then returning an array after operation. Take ruby code as an example.

``````
a = (1..3).to_a; # An array of [1,2,3]
a.map {|x| x*2} # Return a new array [2,4,6]``````

Let's take a look at that long string of code :)

sum and product define functions for adding and multiplying elements;

neg is also a function whose function is equivalent to :product(-1,x), that is, to find the negative value of x;

The square function is equivalent to: Math.pow (x,2), which calculates the square value of x. Notice that the second parameter of partial is undefined, which means that the shape will be filled by the first argument. To be clear: square(x) function is equal to Math.pow (x,2).

The sqrt function is similar to square in that it is equivalent to Math.pow (x,0.5), which is equivalent to calculating x to the open power.
The last function is reciprocal, which is equivalent to Math.pow (x,-1), that is, x to the minus 1, which is equivalent to the inverse of x.

Here is how to knead the above functions in 1 bird :)

Let's look at the calculation of the average first. It's very simple: take the sum of the array elements and multiply it by the reciprocal of the array length, which is the array and/array length.

Finally, for the standard deviation that seems difficult, we'd better look at it from the inside out:
First look at the layer containing neg:

``````
// Is equivalent to a function sum(-1 * mean + x)
partial(sum,neg(mean)``````

Here's the compose function:

``````
// The following equivalent substitution is made on the source code, which can be equivalent to:
//square(sum(-1*mean + x)), Begin again ( I peel , I peel , I peel Onions ...):
//Math.pow(sum(-1*mean + x),2);
compose(square,sum(-1*mean + x))``````

Now let's look at the map function:

// clear! ? That is, each element in data is an x, which is passed into the following function, and a new array of values is returned. That is, the value of each element in the new array is the average of each element in data plus data negative, and then the result is calculated to the power 2.

``````
map(data,Math.pow(sum(-1*mean + x),2))``````

Then look at the reduce function outside map:

``````
// Adds the values of each element of the previous new array.
reduce(map(...),sum)``````

Then take a look at the reciprocal function:

``````
// Converts a class array object into a real array
function array(a,n){
return Array.prototype.slice.call(a,n||0);
}
// Pass the function arguments to the left
function partial_left(f){
var args = arguments;
return function(){
var a = array(args,1);
a = a.concat(array(arguments));
return f.apply(this,a);
};
}
// Pass the arguments of the function to the right
function partial_right(f){
var args = arguments;
return function(){
var a = array(arguments);
a = a.concat(array(args,1));
return f.apply(this,a);
};
}
// The function argument is used as a template,
// In the argument list undefined The value is filled with the actual argument value.
function partial(f){
var args = arguments;
return function(){
var a = array(args,1);
var i = 0,j = 0;
for(;i<a.length;i++)
if(a[i] === undefined)
a[i] = arguments[j++];
a = a.concat(array(arguments,j));
return f.apply(this,a);
};
}
// return 1 The functions are similar to f(g())
function compose(f,g){
return function(){
return f.call(this,g.apply(this,arguments));
};
}``````
0

Let's look at the outer product function:

``````
// Converts a class array object into a real array
function array(a,n){
return Array.prototype.slice.call(a,n||0);
}
// Pass the function arguments to the left
function partial_left(f){
var args = arguments;
return function(){
var a = array(args,1);
a = a.concat(array(arguments));
return f.apply(this,a);
};
}
// Pass the arguments of the function to the right
function partial_right(f){
var args = arguments;
return function(){
var a = array(arguments);
a = a.concat(array(args,1));
return f.apply(this,a);
};
}
// The function argument is used as a template,
// In the argument list undefined The value is filled with the actual argument value.
function partial(f){
var args = arguments;
return function(){
var a = array(args,1);
var i = 0,j = 0;
for(;i<a.length;i++)
if(a[i] === undefined)
a[i] = arguments[j++];
a = a.concat(array(arguments,j));
return f.apply(this,a);
};
}
// return 1 The functions are similar to f(g())
function compose(f,g){
return function(){
return f.call(this,g.apply(this,arguments));
};
}``````
1

The outermost sqrt represents taking the square root of the result obtained by the above division; You can compare the previous non-functional programming code with 1, which is 1 sample :) it looks like a terrible piece of code, and the difficulty will be zero immediately after the analysis. If you still don't understand it, it's a question of the cat's ability to express itself. Welcome to ask.

The explanation is finished, finish off the work, the job is done.