为什么javascript中没有Array.prototype.flatMap?

时间:2016-10-03 18:00:36

标签: javascript functional-programming

flatMap对集合非常有用,但javascript在Array.prototype.map时不提供。为什么呢?

有没有办法在javascript中以简单有效的方式模仿flatMap而无法手动定义flatMap

8 个答案:

答案 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)], [])

MDN Article on flatMap

答案 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);