JavaScript实现一个函数,将数组扁平化(flatten),即把多维数组转为一维数组。

news2025/3/22 14:36:35

大白话实现一个函数,将数组扁平化(flatten),即把多维数组转为一维数组。

思路

实现数组扁平化的基本思路是遍历数组中的每个元素,如果元素是数组,就递归地将其扁平化并添加到结果数组中;如果元素不是数组,就直接添加到结果数组中。

代码示例

function flatten(arr) {
    // 创建一个空数组,用于存储扁平化后的结果
    let flattened = [];
    // 遍历输入数组中的每个元素
    for (let i = 0; i < arr.length; i++) {
        // 检查当前元素是否为数组
        if (Array.isArray(arr[i])) {
            // 如果当前元素是数组,递归调用 flatten 函数对其进行扁平化
            // 并将扁平化后的结果添加到 flattened 数组中
            flattened = flattened.concat(flatten(arr[i]));
        } else {
            // 如果当前元素不是数组,直接将其添加到 flattened 数组中
            flattened.push(arr[i]);
        }
    }
    // 返回扁平化后的数组
    return flattened;
}

// 测试示例
const multiDimensionalArray = [1, [2, [3, 4], 5], 6, [7, 8]];
const flattenedArray = flatten(multiDimensionalArray);
console.log(flattenedArray);

代码解释

  1. 函数定义

    • function flatten(arr):定义了一个名为 flatten 的函数,它接受一个数组 arr 作为参数。
  2. 初始化结果数组

    • let flattened = [];:创建一个空数组 flattened,用于存储扁平化后的结果。
  3. 遍历数组

    • for (let i = 0; i < arr.length; i++):使用 for 循环遍历输入数组 arr 中的每个元素。
  4. 检查元素类型

    • if (Array.isArray(arr[i])):使用 Array.isArray 方法检查当前元素是否为数组。
  5. 递归处理数组元素

    • flattened = flattened.concat(flatten(arr[i]));:如果当前元素是数组,递归调用 flatten 函数对其进行扁平化,并使用 concat 方法将扁平化后的结果添加到 flattened 数组中。
  6. 处理非数组元素

    • flattened.push(arr[i]);:如果当前元素不是数组,直接使用 push 方法将其添加到 flattened 数组中。
  7. 返回结果

    • return flattened;:返回扁平化后的数组。

除了递归,还有其他方法可以实现数组扁平化吗?

除了递归方法,还有几种不同的方式可以实现数组扁平化,下面为你详细介绍:

方法一:使用 reduceconcat 方法

reduce 方法可以对数组中的每个元素执行一个提供的函数,并将其结果汇总为单个值。结合 concat 方法可以有效实现数组扁平化。

function flatten(arr) {
    // 使用 reduce 方法遍历数组
    return arr.reduce((acc, val) => {
        // 如果当前元素是数组,使用 concat 方法将其扁平化后添加到累加器中
        // 如果不是数组,直接添加到累加器中
        return acc.concat(Array.isArray(val)? flatten(val) : val);
    }, []);
}

// 测试示例
const multiDimensionalArray = [1, [2, [3, 4], 5], 6, [7, 8]];
const flattenedArray = flatten(multiDimensionalArray);
console.log(flattenedArray);

此代码中,reduce 方法遍历数组的每个元素,若元素是数组,就递归调用 flatten 函数将其扁平化,再用 concat 方法添加到累加器;若不是数组则直接添加到累加器。

方法二:使用 flat 方法

flat 是 JavaScript 数组自带的方法,能直接实现数组扁平化。可以指定扁平化的深度,若要完全扁平化,可传入 Infinity

const multiDimensionalArray = [1, [2, [3, 4], 5], 6, [7, 8]];
// 使用 flat 方法并传入 Infinity 实现完全扁平化
const flattenedArray = multiDimensionalArray.flat(Infinity);
console.log(flattenedArray);

这种方法简洁直观,直接调用 flat 方法并传入 Infinity 就能把多维数组完全扁平化为一维数组。

方法三:使用 while 循环和 some 方法

通过 some 方法检查数组中是否还有嵌套数组,若有就使用 concat 方法展开,借助 while 循环持续处理,直至没有嵌套数组。

function flatten(arr) {
    let isNested = true;
    // 当数组中还有嵌套数组时继续循环
    while (isNested) {
        isNested = false;
        let newArr = [];
        // 遍历数组
        for (let i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i])) {
                // 如果是数组,将其元素添加到新数组中
                newArr = newArr.concat(arr[i]);
                isNested = true;
            } else {
                // 不是数组则直接添加到新数组
                newArr.push(arr[i]);
            }
        }
        arr = newArr;
    }
    return arr;
}

// 测试示例
const multiDimensionalArray = [1, [2, [3, 4], 5], 6, [7, 8]];
const flattenedArray = flatten(multiDimensionalArray);
console.log(flattenedArray);

此代码利用 while 循环和 some 方法不断检查并展开嵌套数组,直到数组中不存在嵌套数组,最终得到一维数组。

哪种方法实现数组扁平化的效率更高?

递归方法

function flatten(arr) {
    let flattened = [];
    for (let i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
            flattened = flattened.concat(flatten(arr[i]));
        } else {
            flattened.push(arr[i]);
        }
    }
    return flattened;
}
  • 优点:代码逻辑直观,易于理解和实现,适合处理嵌套层级不深、数据规模较小的数组。
  • 缺点:当数组嵌套层级很深时,递归调用会导致大量的函数调用栈,可能引发栈溢出错误,而且函数调用的开销也会使性能下降。

使用 reduceconcat 方法

function flatten(arr) {
    return arr.reduce((acc, val) => {
        return acc.concat(Array.isArray(val)? flatten(val) : val);
    }, []);
}
  • 优点:代码简洁,同样基于递归思想,借助 reduce 方法实现数组遍历和结果累加,处理逻辑清晰。
  • 缺点:和递归方法一样,在处理深度嵌套数组时,由于递归调用过多,会有栈溢出风险,性能也会受影响。

使用 flat 方法

const flattenedArray = multiDimensionalArray.flat(Infinity);
  • 优点:这是 JavaScript 原生提供的方法,由浏览器引擎底层实现,经过高度优化,性能通常较好。使用 Infinity 作为参数能轻松处理任意嵌套深度的数组,代码简洁高效。
  • 缺点:该方法是 ES2019 引入的新特性,对于一些较旧的浏览器版本可能不支持,需要做兼容性处理。

使用 while 循环和 some 方法

function flatten(arr) {
    let isNested = true;
    while (isNested) {
        isNested = false;
        let newArr = [];
        for (let i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i])) {
                newArr = newArr.concat(arr[i]);
                isNested = true;
            } else {
                newArr.push(arr[i]);
            }
        }
        arr = newArr;
    }
    return arr;
}
  • 优点:避免了递归调用,不会有栈溢出问题,在处理深度嵌套数组时性能相对稳定。
  • 缺点:代码逻辑相对复杂,需要多次遍历数组和创建新数组,在处理大规模数组时,频繁的数组操作会带来一定的性能开销。

效率总结

  • 小规模、浅嵌套数组:递归方法、reduceconcat 方法代码简洁易读,性能差异不大,可任选其一。
  • 大规模、深嵌套数组flat 方法效率最高,因为它是原生方法,经过优化;若考虑兼容性,while 循环和 some 方法是不错的选择,能避免栈溢出问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2319614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot最佳实践之 - 使用AOP记录操作日志

1. 前言 本篇博客是个人在工作中遇到的需求。针对此需求&#xff0c;开发了具体的实现代码。并不是普适的记录操作日志的方式。以阅读本篇博客的朋友&#xff0c;可以参考此篇博客中记录日志的方式&#xff0c;可能会对你有些许帮助和启发。 2. 需求描述 有一个后台管理系统…

第六届机电一体化技术与智能制造国际学术会议(ICMTIM 2025)

重要信息 4月11-13日 南京江北新区工业大学亚朵酒店 www.icmtim.org&#xff08;点击了解参会投稿等&#xff09; 简介 由南京工业大学主办&#xff0c;南京工业大学电气工程与控制科学学院、中国矿业大学、黑龙江大学、江苏省自动化学会承办的第六届机电一体化技术…

期刊分区表2025年名单下载(经济学、管理学)

2025年期刊分区表包括SCIE、SSCI、A&HCI、ESCI和OAJ&#xff0c;共设置了包括自然科学、社会科学和人文科学在内的21个大类 本次分享的是期刊分区表2025年名单经济学类、管理学类&#xff0c;一共7631025条 一、数据介绍 数据名称&#xff1a;期刊分区表2025年名单 数据…

八股学习-JUC java并发编程

本文仅供个人学习使用&#xff0c;参考资料&#xff1a;JMM&#xff08;Java 内存模型&#xff09;详解 | JavaGuide 线程基础概念 用户线程&#xff1a;由用户空间程序管理和调度的线程&#xff0c;运行在用户空间。 内核线程&#xff1a;由操作系统内核管理和调度的线程&…

PostgreSQL_数据下载并保存(psycopg2)

目录 前置&#xff1a; 1 数据下载 1.1 多个股票多个交易日 1.2 一个交易日所有股票 2 数据保存&#xff0c;使用python中的psycopg2包 2.1 在PyCharm中创建新项目&#xff0c;并安装包 2.2 代码-多个股票多个交易日 2.3 代码-一个交易日所有股票 2.4 在 pgAdmin4 中…

启明星辰春招面试题

《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇网安资料库https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…

边缘计算革命:重构软件架构的范式与未来

摘要 边缘计算通过将算力下沉至网络边缘&#xff0c;正在颠覆传统中心化软件架构的设计逻辑。本文系统分析了边缘计算对软件架构的范式革新&#xff0c;包括分布式分层架构、实时资源调度、安全防护体系等技术变革&#xff0c;并结合工业物联网、智慧医疗等场景案例&#xff0c…

【读点论文】Chain Replication for Supporting High Throughput and Availability

在分布式系统中&#xff0c;强一致性往往和高可用、高吞吐是矛盾的。比如传统的关系型数据库&#xff0c;其保证了强一致性&#xff0c;但往往牺牲了可用性和吞吐量。而像 NoSQL 数据库&#xff0c;虽然其吞吐量、和扩展性很高&#xff0c;但往往只支持最终一致性&#xff0c;无…

Servlet、Servlet的5个接口方法、生命周期、以及模拟实现 HttpServlet 来写接口的基本原理

DAY15.1 Java核心基础 Servlet Servlet是一个接口&#xff0c;是java的基础&#xff0c;java之所以编写web的程序&#xff0c;接收请求并响应&#xff0c;就是因为Sevlet接口 Java 类实现了Servlet接口的时候就可以接收并响应请求&#xff0c;成为web服务器 Web服务器就是接…

贝叶斯公式的一个直观解释

E E E&#xff1a;抓到娃娃 H H H&#xff1a;坐地铁 H ˉ \bar H Hˉ&#xff1a;坐公交 P ( E ) P ( H ) P ( E ∣ H ) P ( H ‾ ) P ( E ∣ H ‾ ) P({E}) P({H}) P({E} \mid {H}) {P}(\overline{{H}}) {P}({E} \mid \overline{{H}}) P(E)P(H)P(E∣H)P(H)P(E∣H) P (…

Java 大视界 -- Java 大数据分布式计算中的通信优化与网络拓扑设计(145)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

reconstruct_3d_object_model_for_matching例子

文章目录 1.获取om3文件2.准备可视化3.准备3D可视化4.读取3D模型5.显示成对注册结果16.显示成对注册结果27.联合注册模型8.处理图像8.1子采样8.2 图像计算与平滑8.3 三角测量 9.基于表面做3D匹配10.评估模型准确度10.1 在场景中找到模型10.2 计算模型和场景之间的距离 11.立体系…

【JavaWeb学习Day27】

Tlias前端 员工管理 条件分页查询&#xff1a; 页面布局 搜索栏&#xff1a; <!-- 搜索栏 --><div class"container"><el-form :inline"true" :model"searchEmp" class"demo-form-inline"><el-form-item label…

Webrtc编译官方示例实现视频通话

Webrtc编译官方示例实现视频通话 前言 webrtc官网demo中给了一个供我们学习和应用webrtc的一个很好的例子&#xff1a;peerconnection&#xff0c;这期我们就来编译和运行下这个程序看看视频通话的效果以。 1、打开源码工程 继上期源码编译完成后&#xff0c;我们使用vs打开…

大数据学习(80)-数仓分层

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…

刘强东突然发声:不该用算法压榨最底层兄弟!东哥,真正的人民企业家

今天忙了一天&#xff0c;很累&#xff0c;准备睡觉的时候&#xff0c;看到网上盛传的刘强东的朋友圈&#xff0c;东哥又在朋友圈发文了。 说实话&#xff0c;看完之后&#xff0c;感动&#xff0c;真的感动。 尤其是当我看到这两句话的时候。 1、我们所学的知识、商业模式、技…

Java 记忆链表,LinkedList 的升级版

文章目录 记忆链表 MemoryLinkedList实战源代码 众所周知&#xff0c;ArrayList 和 LinkedList 是 Java 集合中两个基本的数据结构&#xff0c;对应数据结构理论中的数组和链表。但在这两个数据结构&#xff0c;开发者们通常使用 ArrayList&#xff0c;而不使用 LinkedList。JD…

poetry安装与使用

文章目录 安装方法创建虚拟环境其他常用命令从 poetry.lock 中安装第三方依赖包 安装方法 安装命令&#xff08;全局安装&#xff0c;不要在虚拟环境中安装&#xff0c;方便后面创建环境使用&#xff09; pip install poetry修改虚拟环境路径&#xff08;首次使用poetry时执行&…

UVM config机制及uvm_resource_pool

目录 1. uvm_config_db 类源码 1.1 set 1.2 get 2. uvm_resource_pool 2.1 uvm_resource_pool::set 2.2 uvm_resource 3. usage 4. 小结 uvm提供一种uvm_config_db机制使得在仿真中通过变量设置来修改环境,使环境更加灵活。本文主要介绍uvm_config_db#(type)::get/set…

JAVA学习*接口

接口 在生活中我们常听说USB接口&#xff0c;那接口是什么呢&#xff1f; 在Java中&#xff0c;接口相当于多个类的一种公共规范&#xff0c;是一种引用数据类型。 定义接口 public interface IUSB {public static final String SIZE "small";public abstract vo…