Javascript 为什么javascript中没有Array.prototype.flatMap?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39837678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why no Array.prototype.flatMap in javascript?
提问by Sergey Alaev
flatMap
is incredibly useful on collections, but javascript does not provide one while having Array.prototype.map
. Why?
flatMap
在集合上非常有用,但是 javascript 在拥有Array.prototype.map
. 为什么?
Is there any way to emulate flatMap
in javascript in both easy and efficient way w/o defining flatMap
manually?
有没有办法以flatMap
简单有效的方式在 javascript 中进行模拟而无需flatMap
手动定义?
回答by Thank you
Update:Array.prototype.flatMap
is on it's way to native ECMAScript. It's currently in Stage 4.
更新:Array.prototype.flatMap
正在向本机 ECMAScript 迈进。目前处于第 4 阶段。
It is widely supported in many environments. See if it works in your browser using this snippet below -
它在许多环境中得到广泛支持。使用以下代码段查看它是否在您的浏览器中有效 -
const data =
[ 1, 2, 3, 4 ]
console.log(data.flatMap(x => Array(x).fill(x)))
// [ 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 ]
Why no Array.prototype.flatMap in javascript?
为什么javascript中没有Array.prototype.flatMap?
Because programming isn't magic and every language doesn't have features/primitives that every other language has
因为编程不是魔术,而且每种语言都没有其他语言都有的特性/原语
What matters is
重要的是
JavaScript gives you the ability to define it on your own
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))
Or a rewrite that collapses the two loops into one
或者重写将两个循环合二为一
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))
If you want it on the Array.prototype
, nothing is stopping you
如果你想要它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]))
回答by Kutyel
flatMap
has been approved by the TC39 as part of ES2019 (ES10). You can use it like this:
flatMap
已被 TC39 批准为 ES2019 (ES10) 的一部分。你可以这样使用它:
[1, 3].flatMap(x => [x, x + 1]) // > [1, 2, 3, 4]
Here's my own implementation of the method:
这是我自己对该方法的实现:
const flatMap = (f, arr) => arr.reduce((x, y) => [...x, ...f(y)], [])
回答by Alan Mimms
I know you said you didn't want to define it yourself, but this implementationis a pretty trivial definition.
我知道你说过你不想自己定义它,但这个实现是一个非常简单的定义。
There's also this from the same github page:
还有来自同一个github页面的这个:
Here is a bit of shorter way using es6 spread, similiar to renaudtertrais's - but using es6 and not adding to the prototype.
这是使用 es6 扩展的一种更短的方法,类似于 renaudtertrais - 但使用 es6 而不是添加到原型中。
var flatMap = (a, cb) => [].concat(...a.map(cb))
const s = (v) => v.split(',')
const arr = ['cat,dog', 'fish,bird']
flatMap(arr, s)
Would either of these help?
这两个有帮助吗?
It should be noted (thanks to @ftor) that this latter "solution" suffers from "Maximum call stack size exceeded" if called on a really large (e.g., 300k elements) array a
.
应该注意(感谢@ftor),如果在一个非常大的(例如,300k 个元素)数组上调用,后一种“解决方案”会受到“超出最大调用堆栈大小”的影响a
。
回答by Matthew Marichiba
Lodashprovides a flatmap function, which to me is practically equivalent to Javascript providing it natively. If you're not a Lodash user, then ES6's Array.reduce()
method can give you the same result, but you have to map-then-flatten in discrete steps.
Lodash提供了一个 flatmap 函数,对我来说这实际上相当于 Javascript 原生提供它。如果您不是 Lodash 用户,那么 ES6 的Array.reduce()
方法可以为您提供相同的结果,但您必须以离散的步骤进行 map-then-flatten。
Below is an example of each method, mapping a list of integers and returning only the odds.
下面是每种方法的示例,映射整数列表并仅返回几率。
Lodash:
洛达什:
_.flatMap([1,2,3,4,5], i => i%2 !== 0 ? [i] : [])
ES6 Reduce:
ES6 减少:
[1,2,3,4,5].map(i => i%2 !== 0 ? [i] : []).reduce( (a,b) => a.concat(b), [] )
回答by JLRishe
One fairly concise approach is to make use of the Array#concat.apply
:
一种相当简洁的方法是使用Array#concat.apply
:
const flatMap = (arr, f) => [].concat.apply([], arr.map(f))
console.log(flatMap([1, 2, 3], el => [el, el * el]));
回答by serhii
I did somthing like this:
我做了这样的事情:
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]
[[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]
[{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]
回答by bigInt
We now have a flatMap()
in Javascript! And it is supported pretty well
我们现在有一个flatMap()
在 Javascript 中!它得到了很好的支持
The flatMap() method first maps each element using a mapping function, then flattens the result into a new array. It is identical to a map() followed by a flat() of depth 1
flatMap() 方法首先使用映射函数映射每个元素,然后将结果展平到一个新数组中。它等同于 map() 后跟深度为 1 的 flat()
const dublicate = x => [x, x];
console.log([1, 2, 3].flatMap(dublicate))
回答by Willem van der Veen
Array.prototype.flatMap()
has now arrived in JS. However, not all browser might support them check for the current browser compatibility the Mozilla web docs.
Array.prototype.flatMap()
现在已经到了JS。但是,并非所有浏览器都支持它们,请检查Mozilla 网络文档中的当前浏览器兼容性。
What the flatMap()
method does is first maps each element using a callback function as argument, then flattens the result into a new array (the 2d array is now 1d since the elements are flattened out).
该flatMap()
方法首先使用回调函数作为参数映射每个元素,然后将结果展平到一个新数组中(二维数组现在是 1d,因为元素被展平了)。
Here is also an example of how to use the function:
这里还有一个如何使用该函数的示例:
let arr = [[2], [4], [6], [8]]
let newArr = arr.flatMap(x => [x * 2]);
console.log(newArr);