高阶函数
1、map/reduce
map:如果我们有一个函数f(x)=x²,要把这个函数作用在一个数组[1,2,3,4,6,5]上,就可以使用map实现。
'use strict';
function pow(x) {
return x * x
}
var arr = [1,2,3,4]
var results = arr.map(pow)
// [1,4,9,16]
map() 作为高阶函数,实质是对数组中的每一项做计算,然后重新保存到新的数组中。
reduce:和map一样也是作用在数组的每一项上,但是函数必须接受2个参数,将上一个元素的计算结果累计到下一个元素中。效果其实就是:
[x1,x2,x3,x4].reduce(f) = f(f(f(x1,x2),x3),x3)
对于数组:
var arr = [1,2,3,7,4]
function sum(x,y) {
return x + y
}
arr.reduce(sum)
// 17
function h(x,y){
return x * y
}
arr.reduce(h)
// 168
2、filter
filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。
和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
例如,在一个Array中,删掉偶数,只保留奇数,可以这么写:
var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
return x % 2 !== 0;
});
// [1, 5, 9, 15]
filter()接收回调函数可以有多个参数,f(element, index, self){}
element: 当前元素
index: 当前元素索引值
self: 数组本身
filter去重
'use strict'
var
r,
arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
r = arr.filter(function (element, index, self) {
return self.indexOf(element) === index;
});
console.log(r);
3、sort()
算法排序:对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1
如果对数组直接进行排序,发现结果:
// 看上去正常的结果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];
// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']
// 无法理解的结果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
这是因为Array的sort()方法默认把所有元素先转换为String再排序,apple在最后,是因为a的ASCI码在大学字母后面,结果'10'排在了'2'的前面,因为字符'1'比字符'2'的ASCII码小。
幸运的是,sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。
要按数字大小排序,我们可以这么写:
'use strict'
var arr = [1,4,11,6,3,6,]
arr.sort(function(x, y) {
return x - y
})
console.log(arr) //[1, 3, 4, 6, 6, 11]
arr.sort(function(x, y) {
return y - x
})
console.log(arr) //[11, 6, 6, 4, 3, 1]
如果需要忽略大小写进行字符串排序,我们需要在函数中将x, y 统一转换为大写或小写进行比较,返回的才能正确
使用方法
1、两个或多个数组合并去重
var arr0 = [1,2,3,4,5]
var arr1 = [2,4,6,8,0]
var arr2 = [5,6,7,8,9]
function arrFilter() {
var arr = Array.prototype.slice.apply(arguments)
arr = arr.reduce(function(x, y){
return x.concat(y)
})
arr = arr.filter(function(ele, index, self){
return self.indexOf(ele) === index
})
return arr
}
console.log(arrFilter(arr0,arr1,arr2))
//[1, 2, 3, 4, 5, 6, 8, 0, 7, 9]
2、两个或多个数组选择没有重复的元素组成一个新数组
var arr0 = [1,2,3,4,5]
var arr1 = [2,4,6,8,0]
var arr2 = [5,6,7,8,9]
function newArr() {
var arr = Array.prototype.slice.apply(arguments)
var newArr = []
arr = arr.reduce(function(x, y){
return x.concat(y)
})
arr = arr.filter(function(ele, index, self){
var length = self.length
var canReturn = self.includes(ele, index+1) || self.indexOf(ele) !== index
return !canReturn
})
return arr
}
console.log(newArr(arr0,arr1,arr2))
// [1, 3, 0, 7, 9]
3、includes() 判断一个数组是否包含一个指定的值,返回布尔值
let a = [1,2,3]
a.includes(2) //true
a.includes(4) //false
语法:
arr.includes(searchElement)
arr.includes(searchElement, fromIndex)
searchElement: 需要查找的元素
fromIndex|可选: 从该索引处开始查找searchElement。如果为负值,则按升序从array.length + fromIndex的索引开始搜索。默认为0。
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
如果fromIndex 大于等于数组长度 ,则返回 false 。该数组不会被搜索。
4、树节点过滤
var tree = [{
id: 1,
text: '中国',
children: [
{
id: 2,
text: '浙江',
children: [
{
id: 3,
text: '杭州',
},
{
id: 4,
text: '丽水',
children: [
{
id: 5,
text: '庆元'
},
{
id: 6,
text: '龙泉'
}
]
},
{
id: 7,
text: '温州',
children: [
{
id: 8,
text: '泰顺'
}
]
},
]
},
{
id: 9,
text: '重复测试',
children: [
{
id: 10,
text: '温州'
}
]
}
]
}]
function filter(arr, val) {
let node = []
arr.map(item => {
if (item.text.indexOf(val) >= 0) {
node.push(item)
return
}
if (item.children && item.children.length > 0) {
let child = filter(item.children, val)
if (child.length > 0) {
item.children = child
node.push(item)
}
return
}
return
})
return node
}
console.log(filter(tree, '温州'))