澳门皇冠官网appstream.js等等都达成了它们自己的更强大的map()、,两者不相同

来个链接 [ 函数式编程
]

即使您精心看了到近来为止出现过的示范代码,你会意识那里面的有些措施不太精通。
它们是map()、filter()和reduce()函数,它们对其他语言的函数式编程都主要。
它们可以让你不用采用循环和言辞,写出更精简的代码。

在函数式编程里面,方法是艺术,函数是函数,两者不相同。

map()、filter()和reduce()函数组成了函数式程序员工具集的中央部分,那一个工具集包罗一一日千里纯的、
高阶的函数,它们是函数式方法的主力。实际上,它们是纯函数和高阶函数的天下第一,它们以一个函数为输入,
重回一个输出结果,并且不爆发副成效。

函数能够当做参数传递给艺术 .

然则它们是浏览器中ECMAScript
5.1的兑现规范,它们只工作于数组。每一回调用它们,一个新的数组会被创设并再次来到,
而原来存在的老大数组不会被改动。它们以函数为输入,平常应用匿名函数作为回调函数。它们遍历数组,
并对数组的每一个要素运用那个函数!

package com.msym

/**
  * Created by msym on 2017/7/4.
  * 函数式编程
  */
object Demo {
  def main(args: Array[String]): Unit = {
    val res1 = m1(fun1, 10, 20)
    println(res1)
    val res2 = m1(fun2, 10, 20)
    println(res2)

  }
  //定义一个方法,接收三个参数:一个函数(仅仅是函数的签名),另外两个是Int类型(函数运行需要的参数)
  def m1(fun : (Int,Int) => Int, x:Int, y:Int) = {
    //调用函数
    fun(x, y)
  }
  //定义一个函数fun1
  val fun1 = (x:Int, y:Int) => x + y
  //定义另个函数fun2
  val fun2 =(x:Int, y:Int) => x * y

  val fun3 = (x:Int) => x
}
myArray = [1,2,3,4];
newArray = myArray.map(function(x) {return x*2});
console.log(myArray); // Output: [1,2,3,4]
console.log(newArray); // Output: [2,4,6,8]

 

还有少数,它们只听从于数组,不可以作用于其余可迭代的数据结构,比如对象。不用顾虑,
有为数不少库比如Underscore.js,Lazy.js,stream.js等等都达成了它们自己的更有力的map()、
filter()和reduce()。

函数式编程掌握例子之一 :

回调

函数代替了 Java 中的匿名类,

scala 中 Array 类的 map()方法, 接收一个函数, 用于对数组内容举办操作 :

package com.msym

/**

  * Created by msym on 2017/7/4.
  * http://www.cnblogs.com/daimajun/
  */
object Demo {
  def main(args: Array[String]): Unit = {
    val arr = Array("aaa", "bbb")
    //原数组
    for (x <- arr)
      println(x)

    //这里的toUpperCase可以加括号, 也可以不加
    val newArr = arr.map(x => x.toUpperCase())
    //新数组
    for (x <- newArr)
      println(x)
  }
}

    打印出:

澳门皇冠官网app 1

对此地点的代码, 有一种更变态的主意, map()方法中传送的函数有所差别,
如下:

val newArr = arr.map(_.toUpperCase)

那里的下划线 “_” 代表的是每一回数组中取出的要素, 然后将其转为大写.

若是你此前平昔没用过回调,这那么些概念可能会让你有些迷惑。越发是在Javascript中,
Javascript给出了一点种申明函数的措施。

回调函数用于传递给别的一个函数供它们利用,那是一种像传递对象一样来传递逻辑的法子:

var myArray = [1,2,3];
function myCallback(x){return x+1};
console.log(myArray.map(myCallback));

对此比较简单的职务可以用匿名函数:

console.log(myArray.map(function(x){return x+1}));

回调不仅用于函数式编程,在Javascript中它们能干很多业务。仅作为例子,那有个callback()函数用于jQuery的AJAX调用:

function myCallback(xhr) {
 console.log(xhr.status);
 return true;
}
$.ajax(myURI).done(myCallback);

注意那里只用了函数的名字,因为我们并不是要调用函数而是传递函数,写成那样就错了:

$.ajax(myURI).fail(myCallback(xhr)); 
// 或者
$.ajax(myURI).fail(myCallback());

若果大家调用了函数会时有爆发什么样?在那些事例里,myCallback(xhr)会尝试举行,控制台将打印“undefined”,
并会重临true。当ajax()完结调用时,它依据名字找到的回调函数将是一个”true”,然后就报错了。

也就是说我们无能为力指定给回调函数传什么参数,即使大家的回调函数要求让ajax()函数传给他大家想要的参数,
大家得以把回到函数包在一个匿名函数里:

function myCallback(status) {
 console.log(status);
 return true;
}
$.ajax(myURI).done(function(xhr) {
 myCallback(xhr.status)
});

Array.prototype.map()

map()是这么些函数的非常,它大约地对数组里的因素依此应用回调函数。

语法:arr.map(callback [, thisArg]);

参数:
•callback(): 那一个函数为新数组爆发一个要素,它接受的参数:
◦currentValue:数组当前遍历到的元素
◦index:数组中当前元素序数
◦array:当前正值处理的数组

•thisArg:那是个可选参数,当执行回调的时候它当作回调函数的this

例子:

var
 integers = [1, -0, 9, -8, 3],
 numbers = [1, 2, 3, 4],
 str = 'hello world how ya doing?';

// 将整数映射为他们自己的绝对值
console.log(integers.map(Math.abs));

// 将数组中的元素与自己的位置序数相乘
console.log(numbers.map(function(x, i) {
 return x * i
}));
// 单词隔一个变一个大写
console.log(str.split(' ').map(function(s, i) {
 if (i % 2 == 0)
  return s.toUpperCase();
 else
  return s;
}));

即便Array.prototype.map方法是Javascript中数组对象的正儿八经方法,你也足以很简单地扩张自己的对象。

MyObject.prototype.map = function(f) {
  return new MyObject(f(this.value));
 }; 

Array.prototype.filter()

filter()函数用于把数组中的一些因素筛选出来。回调函数必须回到真(保留到新数组里)或假(扔掉)。
用map()可以做类似的业务,就是把您像扔掉的因素重回为null,不过filter()函数会在新数组里面删除那一个毫无的元素,
而不是留个null占着地方。

语法:arr.filter(callback [, thisArg]);

•callback():这些函数用来测试数组中的每个元素,要保留重返真,否则重临假。它有这一个参数:
◦currentValue:数组当前遍历到的要素
◦index:数组中当前因素的序数
◦array:当前正在处理的数组

•thisArg:那是个可选参数,当执行回调的时候它看成回调函数的this

例子:

var myarray = [1, 2, 3, 4]
words = 'hello 123 world how 345 ya doing'.split(' ');
re = '[a-zA-Z]';
// 筛选整数
console.log([-2, -1, 0, 1, 2].filter(function(x) {
 return x > 0
}));
// 筛选所有含字母的单词
console.log(words.filter(function(s) {
 return s.match(re);
}));
// 随机移除数组中的元素
console.log(myarray.filter(function() {
 return Math.floor(Math.random() * 2)
}));

Array.prototype.reduce()

reduce()函数,有时也号称fold,它用于把数组中的所有值聚集到一起。回调要求重回组合对象的逻辑。
对于数字来说,它们往往会被加到一起或者乘到一起。对于字符串来说,它们往往是被追加到一块。

语法:arr.reduce(callback [, initialValue]);

参数
•callback():此函数把四个对象合并成一个对象,并将其归来。参数有:
◦previousValue:上三遍回调函数被调用时再次来到的值,或者是起头值(即使局地话)
◦currentValue:数组当前正在处理的因素
◦index:数组中当前因素的序数
◦array:当前正在处理的数组

•initialValue:可选。第五次回调所传诵参数的起始值

例子

var numbers = [1, 2, 3, 4];

// 把数组中所有的值加起来
console.log([1, 2, 3, 4, 5].reduce(function(x, y) {
 return x + y
}, 0));

// 查找数组中最大的值
console.log(numbers.reduce(function(a, b) {
  return Math.max(a, b) // max()函数只能有两个参数
 }) 
);

其余函数

map()、filter()和reduce()函数在我们帮助函数的工具箱里并不孤单。那里还有愈来愈多的函数大概在有着函数式应用里都会被选择。

Array.prototype.forEach

forEach()函数本质上是map()函数的非纯版本,它会遍历整个数组,并对每个元素运用回调。
但是那个回调函数不重回值。它是促成for循环的一个更纯粹的主意。

语法:arr.forEach(callback [, thisArg]);

参数:
•callback():对数组中每一个因素所拔取的。参数有:
◦currentValue:数组中当前正在处理的元素
◦index:数组中当前元素的序数
◦array:正在处理的数组

•thisArg:可选。回调函数中作为this的值

例子:

var arr = [1, 2, 3];
var nodes = arr.map(function(x) {
 var elem = document.createElement("div");
 elem.textContent = x;
 return elem;
});

// 对每一个元素的值输出日志
arr.forEach(function(x) {
 console.log(x)
});

// 把节点追加到DOM上
nodes.forEach(function(x) {
 document.body.appendChild(x)
});

Array.prototype.concat

若是不用for或while处理数组,你会不时索要把数组拼接起来。另一个Javascript内建函数concat就是专程干那事情的。
concat函数会回来一个新数组但不改动旧数组。它可以把你传入的所有参数拼接到一起。
console.log([澳门皇冠官网app,1, 2, 3].concat([‘a’,’b’,’c’]) // 拼接七个数组
// Output: [1, 2, 3, ‘a’,’b’,’c’]

它回到三个数组拼接成的数组,同时原来的那些数组没有被更改。那就代表concat函数可以链式调用。

var arr1 = [1,2,3];
var arr2 = [4,5,6];
var arr3 = [7,8,9];
var x = arr1.concat(arr2, arr3);
var y = arr1.concat(arr2).concat(arr3));
var z = arr1.concat(arr2.concat(arr3)));
console.log(x);
console.log(y);
console.log(z);

变量x、y、z的值最终都是[1,2,3,4,5,6,7,8,9]。

Array.prototype.reverse

那么些Javascript内建函数是用来数组变形的。reverse函数用于将一个数组反转,也就是第个一元素会跑到最终,
而最后一个因素变为了首个要素。

只是,那个函数并不会回到一个新的数组,而是把本来的数组替换掉了。大家得以做个更好的。上面是一个纯的反转数组函数

var invert = function(arr) {
 return arr.map(function(x, i, a) {
  return a[a.length - (i + 1)];
 });
};
var q = invert([1, 2, 3, 4]);
console.log(q);

Array.prototype.sort

与map()、filter()和reduce()函数相似,排序函数sort()必要传入一个回调函数来定义数组如何排序。
不过,跟reverse()一样,它也会把原来的数组替换。那可不太好。
arr = [200, 12, 56, 7, 344];
console.log(arr.sort(function(a,b){return a–b}) );
// arr现在是: [7, 12, 56, 200, 344];

大家得以写一个纯函数的sort(),可是排序算法的源代码很费劲。对于专门大的数组,应当根据特定的数据结构来接纳适合的算法,
比如快捷排序、合并排序、冒泡排序等等。

Array.prototype.every 和 Array.prototype.some

Array.prototype.every() 和 Array.prototype.some()
都是纯的高阶函数,它们是Array对象的法门,
通过回调函数依据数组各要素再次回到的布尔值(或一定于布尔的值)来拓展测试。如若数组中有着的因素通过回调函数统计都回来True,
every()函数就回来true;借使数组中有一个元素再次来到True,some()函数就赶回True。

例子:

function isNumber(n) {
 return !isNaN(parseFloat(n)) && isFinite(n);
}
console.log([1, 2, 3, 4].every(isNumber)); // Return: true
console.log([1, 2, 'a'].every(isNumber)); // Return: false
console.log([1, 2, 'a'].some(isNumber)); // Return: true

你或许感兴趣的小说:

相关文章