使用flat()和flatMap()在VanillaJavaScript中展平数组
像 Lodash 和 Underscore.js 这样的库已经为我们提供了一些实用工具来帮助我们扁平化数组。 由于 ECMAScript 标准的不断发展,我们现在将获得直接在 vanilla JavaScript 中执行此操作的方法,而无需外部实用程序函数。
如果您最近一直关注互联网,您可能已经看到,这些扁平化数组的新方法引起了不小的轰动。 现在在 #Smooshgate 上为人所知,它的要点是 Array.prototype.flatten() 正在被 MooTools 进行猴子补丁,某些网站仍在使用它,所以在某些时候出现了一个建议 -最多将方法命名为 smoosh 而不是 flatten 作为一个笑话,以避免破坏一些仍然依赖 MooTools 的网站。 很多人都认真对待了 smoosh 建议,并且为此丢失了相当多的按键。
现在这个小争议已经尘埃落定,最终的决定是使用 flat 和 flatMap 作为两个方法名称来帮助在 JavaScript 中扁平化数组。
现在让我们来看看它们。
Array.prototype.flat()
顾名思义,Array 原型上可用的 flat() 方法返回一个新数组,它是调用它的数组的扁平化版本。 如果没有传入参数,则假定深度为 1。 否则,如果一个数字作为第一个参数传入,它将用作展平数组的最大深度。
这是一个简单的例子:
const animals = [['🐕', '🐶'], ['😺', '🐈']]; const flatAnimals = animals.flat(); // same as: const flatAnimals = animals.flat(1); console.log(flatAnimals); // ['🐕', '🐶', '😺', '🐈']
并注意当数组的总深度大于 flat 方法的最大深度时会发生什么:
const animals = [['🐕', '🐶'], ['😺', '🐈', ['😿',['🦁'], '😻']]]; const flatAnimals = animals.flat(2); console.log(flatAnimals); // ['🐕', '🐶', '😺', '🐈', '😿',['🦁'], '😻']
如果要展平任意深度的数组,可以使用 Infinity:
const animals = [['🐕', '🐶'], ['😺', '🐈', ['😿',['🦁'], '😻']]]; const flatAnimals = animals.flat(Infinity); console.log(flatAnimals); // ['🐕', '🐶', '😺', '🐈', '😿', '🦁', '😻']
Array.prototype.flatMap()
Array 原型上可用的 flatMap() 方法与使用 map() 方法后跟默认深度的 flat() 方法具有相同的效果1。 换句话说,flatMap() 将每个值映射到一个新值,然后将生成的数组展平到最大深度 1。
这是一个例子:
const animals = ['🐕', '🐈', '🐑', '🐮']; const noises = ['woof', 'meow', 'baa', 'mooo']; const mappedOnly = animals.map((animal, index) => [animal, noises[index]]); const mappedAndFlatten = animals.flatMap((animal, index) => [animal, noises[index]]); console.log(mappedOnly); // [['🐕', 'woof'], ['🐈', 'meow'], ['🐑', 'baa'], ['🐮', 'mooo'] console.log(mappedAndFlatten); // ['🐕', 'woof', '🐈', 'meow', '🐑', 'baa', '🐮', 'mooo']
传入 flatMap() 的回调函数需要与可以传入传统 map() 方法的参数相同的参数,第一个是当前值,第二个是数组中当前值的索引,第三个是被映射的完整数组。
浏览器支持
支持已经相当不错了,最新版本的浏览器支持这两种方法。 例如,Chrome 69+、Firefox 62+ 和 Safari 12+ 支持这些方法。 在撰写本文时,目前不支持任何版本的 Internet Explorer 或 Edge。
如果你想现在开始使用它并支持所有浏览器,你总是可以使用官方的 polyfill/shim 来支持 flat 和 flatMap。