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

新手上路,请多包涵

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

有没有什么方法可以在javascript中以简单有效的方式模拟 flatMap 而无需手动定义 flatMap

原文由 Sergey Alaev 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 430
2 个回答

更新: Array.prototype.flatMap 进入ES2019

它在许多环境中得到广泛支持。使用下面的代码片段查看它是否适用于您的浏览器 -

 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 ]

“为什么 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((r, x) => r.concat(f(x)), [])

const xs = [1,2,3]

console.log(flatMap(x => [x-1, x, x+1], xs))

如果你想让它扩展 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','♧']
// ]

原文由 Mulan 发布,翻译遵循 CC BY-SA 4.0 许可协议

flatMap 已被 TC39 批准为 ES2019 (ES10) 的一部分。你可以像这样使用它:

 [1, 3].flatMap(x => [x, x + 1]) // > [1, 2, 3, 4]

这是我自己实现的方法:

 const flatMap = (f, arr) => arr.reduce((x, y) => [...x, ...f(y)], [])

MDN 关于 flatMap 的文章

原文由 Kutyel 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题