目录
- 一、递归
- 二、reduce
- 三、apply+some
- 四、ES6展开运算符
- 五、toString
- 六、正则
- 七、实现自己的扁平化工具方法
- 写在最后
(免费学习推荐:javascript视频教程)
一、递归
for循环是我们在进行数组操作时最容易想到的,在不考虑时间和空间复杂度的时候,递归应该是一个完美的选择!
示例:
输入 const arr = [1, [2, [3, 4, { a: 1 }], null], undefined];` 输出 [ 1, 2, 3, 4, { a: 1 }, null, undefined ]
代码:
function flatten(arr) { let res = []; for (let i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { // 因为函数返回的是数组,所以要做拼接处理 res = res.concat(flatten(arr[i])); } else { res.push(arr[i]) } } return res;}
注意:
- 判断数组内元素的基本类型
- 如果不是数组:直接存入新数组中
- 如果是数组:重复第一步,直到将最后一个不是数组的元素存入到新数组中
二、reduce
先来看看reduce
是做什么的:reduce()
方法对数组中的每个元素执行一个由您提供的reducer函数
(升序执行),将其结果汇总为单个返回值。
示例:
输入 const arr = [1, [2, [3, 4, { a: 1 }], null], undefined];` 输出 [ 1, 2, 3, 4, { a: 1 }, null, undefined ]
代码:
function flatten(arr) { return arr.reduce((prev, next) => { // prev表示上一次操作的结果 return prev.concat(Array.isArray(next) ? flatten(next) : next) }, []) // 注意reduce的初始值应该是[],否则无法进行拼接}
注意:
仔细对照方法一和方法二,两者思路完全一致——找到数据类型是数组的子元素,对其进行抹平处理,只不过实现的细节略有不同。
唯一需要注意的地方就是拼接时数据的基本类型要以数组开始。
三、apply+some
既然方法二是方法一的变式,那个方法三也可以说是方法二的变式,但不在采用递归的方式,而是一层一层“拆除”嵌套的方式
先来看看用到的API:
-
apply
:调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。 -
some
:测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值
代码:
function flatten(arr) { while (arr.some(item => Array.isArray(item))) { // 只要存在数组类型的元素,就抹平一层 arr = [].concat.apply([], arr) } return arr;}
注意:
大家疑惑的点主要在apply
,其实主要目的就是减少括号
let res = [];res = res.concat({});// 等价于[].concat.apply([], [{}])
在本例中:
arr = [].concat.apply([], arr);// 等价于[].concat(1, [2, [3, 4, { a: 1 }], null], undefined)
四、ES6展开运算符
大家可能业也注意到了,方法一到方法三 我们不断的借助现有方法,以精简我们的代码量,本方法也是如此~
我们利用ES6的展开运算符(用于取出参数对象的所有可遍历属性,拷贝到当前对象之中),继续精简方法三:
代码:
function flatten(arr) { while (arr.some(item => Array.isArray(item))) { // 只要存在数组类型的元素,就抹平一层 arr = [].concat(...arr) } return arr;}
五、toString
如果前面四个方法是我们可以实现的主流的方式,那么接下来的几个就是我们可以实现的“非主流”方式,直接上代码!
function flatten(arr) { return arr.toString().split(',').map(function(item){ return +item })}
注意:
将数据转换类型存在类型的限制,如果原始数据是这样的:[1, ‘2’],那么就会出现问题
六、正则
假如我们默认了类型会被转换这一缺陷,那么还可以通过更暴力里的方式来将数组扁平化:
function flatten(arr) { return JSON.stringify(arr).replace(/\[|\]/g, '').split(',');}
注意:
如果是纯数组,貌似没什么问题
function flatten(arr) { return JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g, '').split(',') + ']')}
但如果数组内存在对象,就需要消除JSON后的后果,这样更严谨一些~
到这里,六种方法算是包括了大部分数组扁平化的实现,那么如果希望将我们的方法“升级”成工具怎么办?这时候我们就要“抄袭”一下loadsh了~
七、实现自己的扁平化工具方法
这里我们简化了loadsh里的flatten函数,具体改动我们来看代码:
/* * @private * @param {Array} array 需要扁平化的数组 * @param {number} depth 最多处理几层 * @param {boolean} [isStrict] 是否严格处理函数 * @param {Array} [result=[]] 输出的数组 * @returns {Array} */function flatten(array, depth, isStrict, result) { result || (result = []) // 边界 if (array == null) return result; for (const value of array) { if (depth > 0 && Array.isArray(value)) { if (depth > 1) { flatten(value, depth - 1, isStrict, result) } else { result.push(...value); // 只拆1层 } } else if (!isStrict) { result[result.length] = value } } return result;}
- 该方法提供了扁平化层数
const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 1, false);// [ 1, 2, 3, 4, [ 5, 6 ], { a: 1 }, null, undefined ]
- 该方法提供了扁平化后相反的效果
const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 1, true);// [ 3, 4, [ 5, 6 ] ]const res = flatten([1, 2, [3, 4, [5, 6]], { a: 1 }, null, undefined], 2, true);// [ 5, 6 ]
isStrict
参数打开后,扁平后保留了被暴漏出来的元素,剔除了浅层元素。
写到这里我们即了解了扁平化的处理思路,也有了一定的实现能力,如果你能完全理解上面的代码,相信扁平化这一部分应该难不到你了,我们下一篇文章继续研究loadsh的另一个方法~
相关免费学习推荐:javascript(视频)
以上是JavaScript专题之八:数组扁平化的详细内容。更多信息请关注PHP中文网其他相关文章!

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

Dreamweaver CS6
视觉化网页开发工具

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!