flatMap
对集合非常有用,但javascript在Array.prototype.map
时不提供。为什么呢?
有没有办法在javascript中以简单有效的方式模仿flatMap
而无法手动定义flatMap
?
答案 0 :(得分:52)
为什么javascript中没有Array.prototype.flatMap?
因为编程不是魔术,并且每种语言都没有其他语言所具有的特征/原语
重要的是
JavaScript使您能够自己定义
const concat = (x,y) =>
x.concat(y)
const flatMap = (f,xs) =>
xs.map(f).reduce(concat, [])
const xs = [1,2,3]
console.log(flatMap(x => [x-1, x, x+1], xs))
或者将两个循环折叠成一个
的重写
const flatMap = (f,xs) =>
xs.reduce((acc,x) =>
acc.concat(f(x)), [])
const xs = [1,2,3]
console.log(flatMap(x => [x-1, x, x+1], xs))
如果你想要它Array.prototype
,没有什么能阻止你
const concat = (x,y) =>
x.concat(y)
const flatMap = (f,xs) =>
xs.map(f).reduce(concat, [])
Array.prototype.flatMap = function(f) {
return flatMap(f,this)
}
const xs = [1,2,3]
console.log(xs.flatMap(x => [x-1, x, x+1]))
更新:Array.prototype.flatMap
正在使用原生ECMAScript。它目前处于第3阶段。
答案 1 :(得分:37)
我认为现在是时候宣布TC39已经<{1}} 批准作为ES2019(ES10)的部分
并且还给出了我的方法实现(更像2017年;)
flatMap
享受!
const flatMap = (f, arr) => arr.reduce((x, y) => [...x, ...f(y)], [])
答案 2 :(得分:9)
我知道你说你不想自己定义,但是this implementation是一个非常简单的定义。
同样的github页面也有这个:
这是使用es6 spread的一种较短的方式,类似于renaudtertrais的 - 但是使用es6而不是添加到原型中。
var flatMap = (a, cb) => [].concat(...a.map(cb))
const s = (v) => v.split(',')
const arr = ['cat,dog', 'fish,bird']
flatMap(arr, s)
这些都有帮助吗?
应该注意(感谢@ftor)如果在一个非常大的(例如,300k元素)数组a
上调用,后一个“解决方案”会遇到“超出最大调用堆栈大小”。
答案 3 :(得分:5)
Lodash提供了一个flatmap函数,对我来说实际上相当于本机提供它的Javascript。如果您不是Lodash用户,那么ES6的Array.reduce()
方法可以为您提供相同的结果,但您必须以不连续的步骤进行映射然后展平。
下面是每个方法的示例,映射整数列表并仅返回赔率。
<强> Lodash:强>
_.flatMap([1,2,3,4,5], i => i%2 !== 0 ? [i] : [])
ES6减少:
[1,2,3,4,5].map(i => i%2 !== 0 ? [i] : []).reduce( (a,b) => a.concat(b), [] )
答案 4 :(得分:1)
我做了这样的事情:
Array.prototype.flatMap = function(selector){
return this.reduce((prev, next) =>
(/*first*/ selector(prev) || /*all after first*/ prev).concat(selector(next)))
}
[[1,2,3],[4,5,6],[7,8,9]].flatMap(i => i); //[1, 2, 3, 4, 5, 6, 7, 8, 9]
[{subarr:[1,2,3]},{subarr:[4,5,6]},{subarr:[7,8,9]}].flatMap(i => i.subarr); //[1, 2, 3, 4, 5, 6, 7, 8, 9]
答案 5 :(得分:1)
一种相当简洁的方法是使用Array#concat.apply
:
const flatMap = (arr, f) => [].concat.apply([], arr.map(f))
console.log(flatMap([1, 2, 3], el => [el, el * el]));
答案 6 :(得分:0)
我们现在在Javascript中有了flatMap()
!并且受支持pretty well
flatMap()方法首先使用映射函数映射每个元素, 然后将结果展平为新数组。它与map()相同 然后是深度为1的flat()
const dublicate = x => [x, x];
console.log([1, 2, 3].flatMap(dublicate))
答案 7 :(得分:0)
Array.prototype.flatMap()
现在已到达JS。但是,并非所有浏览器都支持它们,请检查Mozilla web docs是否与当前浏览器兼容。
flatMap()
方法的作用是,首先使用回调函数作为参数映射每个元素,然后将结果展平为新数组(由于元素被展平,因此2d数组现在为1d)。
这也是如何使用该功能的示例:
let arr = [[2], [4], [6], [8]]
let newArr = arr.flatMap(x => [x * 2]);
console.log(newArr);