简体   繁体   English

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

[英]Why no Array.prototype.flatMap in javascript?

flatMap is incredibly useful on collections, but javascript does not provide one while having Array.prototype.map . flatMap在集合上非常有用,但是 javascript 在拥有Array.prototype.map不提供。 Why?为什么?

Is there any way to emulate flatMap in javascript in both easy and efficient way w/o defining flatMap manually?有没有办法以简单有效的方式在 javascript 中模拟flatMap ,而flatMap手动定义flatMap

Update: Array.prototype.flatMap made it into ES2019更新: Array.prototype.flatMap进入 ES2019

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((r, x) => r.concat(f(x)), []) const xs = [1,2,3] console.log(flatMap(x => [x-1, x, x+1], xs))

If you want it to extend the Array.prototype , nothing is stopping you -如果你想让它扩展Array.prototype ,没有什么能阻止你 -

 if (!Array.prototype.flatMap) { function flatMap (f, ctx) { return this.reduce ( (r, x, i, a) => r.concat(f.call(ctx, x, i, a)) , [] ) } Array.prototype.flatMap = flatMap } const ranks = [ 'J', 'Q', 'K', 'A' ] const suits = [ '♡', '♢', '♤', '♧' ] const result = ranks.flatMap(r => suits.flatMap(s => [[r, s]] ) ) console.log(JSON.stringify(result)) // [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧'] // , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧'] // , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧'] // , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧'] // ]

flatMap has been approved by the TC39 as part of ES2019 (ES10). flatMap已被 TC39 批准为 ES2019 (ES10) 的一部分。 You can use it like this:你可以这样使用它:

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

MDN Article on flatMap 关于 flatMap 的 MDN 文章

I know you said you didn't want to define it yourself, but this implementation is 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 (eg, 300k elements) array a .应该注意(感谢@ftor),如果在一个非常大的(例如,300k 个元素)数组a上调用,后一种“解决方案”会受到“超出最大调用堆栈大小” a

Lodash provides a flatmap function, which to me is practically equivalent to Javascript providing it natively. Lodash提供了一个 flatmap 函数,对我来说这实际上相当于 Javascript 原生提供它。 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 用户,那么 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), [] )

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]));

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]

[{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]

We now have a flatMap() in Javascript!我们现在在 Javascript 中有一个flatMap() And it is supported pretty well它得到了很好的支持

The flatMap() method first maps each element using a mapping function, then flattens the result into a new array. flatMap() 方法首先使用映射函数映射每个元素,然后将结果展平到一个新数组中。 It is identical to a map() followed by a flat() of depth 1它等同于 map() 后跟深度为 1 的 flat()

 const dublicate = x => [x, x]; console.log([1, 2, 3].flatMap(dublicate))

Array.prototype.flatMap() has now arrived in JS. Array.prototype.flatMap()现在已经在 J​​S 中出现了。 However, not all browser might support them check for the current browser compatibility the Mozilla web docs .但是,并非所有浏览器都支持它们,请检查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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Array.prototype.flatMap() JS 在测试用例和 repl.it 片段中表现异常,但在浏览器控制台中没有 - Array.prototype.flatMap() JS is behaving strangely in test cases and a repl.it snippet, but not in browser console ESLint 8.31.0“错误:无法加载在‘.eslintrc.js » eslint-config-standard’中声明的插件‘import’:找不到模块‘array.prototype.flatmap’” - ESLint 8.31.0 "Error: Failed to load plugin 'import' declared in '.eslintrc.js » eslint-config-standard': Cannot find module 'array.prototype.flatmap" 类似于Java中的Array.prototype.join的地图或平面图 - Map or flatmap that works like Array.prototype.join in Javascript Javascript - 数组上的 flatMap 方法 - (flatMap 不是函数) - Javascript - flatMap method over array - (flatMap is not a function) 如何在 JavaScript 中的 flatMap 数组方法中获取累加器(flatmap vs reduce)? - How to get accumulator in flatMap array methode in JavaScript(flatmap vs reduce)? 关于 JavaScript 数组原型 - Regarding with JavaScript array prototype Javascript自定义数组原型 - Javascript custom array prototype 具有数组原型的javascript对象 - javascript object with array prototype 具有数组和原型javascript的功能 - Function with array and prototype javascript 数组中的javascript原型循环 - javascript prototype loop for in array
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM