map/reduce/filter
学了 Python 和 JavaScript,在使用 map/reduce 时感觉总弄混/记错,记录一下方便后续查看
Python
map()
- 第一个参数是
f
,即函数对象 本身 - 第二个是
Iterable
(可迭代对象),map
将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterable
返回
举例应用:
- 乘积
- 数字和字符串在数组中相互转换
- 求余
# 乘积
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> def mult(x): # 一个参数
return x * 10
>>> b = map(mult, a)
>>> list(b)
[10, 20, 30, 40, 50, 60, 70, 80]
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
# 拼接(数组中的 数字和字符串 相互转换)
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> ','.join(map(str, a)).split(',') # 第一种方法
['1', '2', '3', '4', '5', '6', '7', '8']
>>> b = list(map(str, a)) # 第二种方法
>>> b
['1', '2', '3', '4', '5', '6', '7', '8']
>>> list(map(int, b))
[1, 2, 3, 4, 5, 6, 7, 8]
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
# 求余
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> print(list(map(lambda x: x%3, a)))
[1, 2, 0, 1, 2, 0, 1, 2]
#使用列表解析
>>> print([x%3 for x in a])
[1, 2, 0, 1, 2, 0, 1, 2]
reduce()
- 第一个参数是
f
,即函数对象 本身,这个函数必须接受两个参数 - 第二个是
Iterable
(序列),把一个函数作用在一个序列上,reduce
把结果继续和序列的下一个元素做累积计算
举例应用:
- 累加
- 累积
- 数组去重
>>> from functools import reduce
# 累加
>>> def add(x, y): # 两个参数
return x + y
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> c = reduce(add, a)
>>> c
36
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
# 累积
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> reduce(lambda x,y: x*y, a)
40320
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
# 数组去重
>>> a = [1, 3, 4, 3, 1, 5, 1, 5]
>>> def result(x, y):
if y not in x:
x.append(y)
return x
>>> reduce(result, a, [])
[1, 3, 4, 5]
filter()
- 第一个参数是
f
,即函数对象 本身 - 第二个是
Iterable
(可迭代对象),和map
不同的是,filter
把传入的函数依次作用于每个元素,然后根据返回值是True
还是False
决定保留还是丢弃该元素
举例应用:
- 找到基数偶数
- 过滤数字
# 求基数
>>> a = [1, 2, 3, 4, 5, 6, 7, 8]
>>> def is_odd(n): # 一个参数
return n % 2 == 1
>>> d = filter(is_odd, a)
>>> list(d)
[1, 3, 5, 7]
# 求偶数
>>> a = [1,2,3,4,5,6,7,8]
>>> print(list(filter(lambda x: x%2==0, a)))
[2, 4, 6, 8]
JavaScript
Array.map()
- 会根据传递的转换函数,更新给定数组中的每个值,并返回一个相同长度的新数组。它接受一个回调函数作为参数,用以执行转换过程
举例应用:
- 累积
- 数字和字符串相互转换
- 可以输出 索引和值 (暂时没想到应用地方)
// 1.最开始写的
function mult(x) {
return x * 10
}
let a = [1, 2, 3, 4, 5, 6, 7, 8]
let b = a.map(mult)
// 2.整合到一起
let c = a.map(function (x) {
return x * 10
})
// 3.ES6写法
let d = a.map(x => x * 10)
console.log(d)
// [ 10, 20, 30, 40, 50, 60, 70, 80 ]
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
// 拼接(数组中的 数字和字符串 相互转换)
let a = [1, 2, 3, 4, 5, 6, 7, 8]
a.toString().split(',') // 第一种方法
// ['1', '2', '3', '4', '5', '6', '7', '8']
let b = a.map(String) // 第二种方法
// ['1', '2', '3', '4', '5', '6', '7', '8']
b.map(Number)
[1, 2, 3, 4, 5, 6, 7, 8]
// *注意:这里不能使用 parseInt,因为map中包含 item,index 两个参数
// 会让每一个元素,按照其索引进行 进制转换(进制需在2~36之间,不在的为NaN)
b.map(parseInt)
// [1, NaN, NaN, NaN, NaN, NaN, NaN, NaN]
let arr = [10.18, 0, 111, 215, 23]
arr.map(parseInt)
// 10, NaN, 7, 7, 11]
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
let a = [1, 5, 7]
a.map(function(val, idx){
console.log(val, idx)
})
// 1 0
// 5 1
// 7 2
Array.reduce()
- 接受一个数组作为输入值并返回一个值。reduce 接受一个回调函数,这个回调函数必须接受两个参数,reduce 把结果继续和序列下一个元素做累积计算
应用举例:
- 累加
- 累积
- 求数组最大值
- 统计词频
- 展平数组
let a = [1, 2, 3, 4, 5, 6, 7, 8]
a.reduce((x, y) => x + y) // 36
a.reduce((x, y) => x * y) // 40320
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
// 求数组最大值
let a = [1, 3, 4, 2, 8, 5, 7, 6]
// reduce initialValue(0, 可选) 如果没有提供初始值,则将使用数组中的第一个元素
a.reduce((acc, cur) => Math.max(acc, cur), 0) // 8
// Math.max()不支持数组
Math.max.apply(null, a) // 8
// 数组sort()
a.sort((num1, num2) => num1 - num2 < 0)[0] // 8
// ES6扩展运算符
Math.max(...a) // 8
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
// 统计词频(类似Python的counter)
let a = [1, 3, 4, 3, 1, 5, 1, 5]
a.reduce((all, num) => {
if (num in all) {
all[num]++
} else {
all[num] = 1
}
return all
}, {})
// { '1': 3, '3': 2, '4': 1, '5': 2 }
''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''
// 展平数组,返回一维数组 类似Python numpy.flatten()
let a = [[0, 1],[2, 3],[4, 5]]
print(a.reduce((acc, cur) => acc.concat(cur), []))
// [ 0, 1, 2, 3, 4, 5 ]
Array.filter()
- 当我们想要过滤数组的值到另一个数组时,就可以用上filter
举例应用:
- 找到基数偶数
- 过滤数字
let a = [1, 2, 3, 4, 5, 6, 7, 8]
a.filter(val => val > 5) // [ 6, 7, 8 ]
a.filter(val => val % 2 === 0) // [ 2, 4, 6, 8 ]
区别
Python中是函数,数组需要写在括号里面,去被执行这个函数
JavaScript中是方法,数组需要写在外面,去调用这个方法
-
Python:
map(fn, arr)
-
JavaScript:
arr.map(fn)
-
Python:
reduce(fn, arr)
-
JavaScript:
arr.reduce(fn)
-
Python:
filter(fn, arr)
-
JavaScript:
arr.filter(fn)