多维数组操作,不要再用遍历循环foreach了!来试试数组展平的小妙招!array.flat()用法与array.flatMap() 用法及二者差异详解

news2025/1/20 6:03:52

目录

一、array.flat()方法

1.1、array.flat()的语法及使用

①语法

②返回值

③用途

二、array.flatMap() 方法

2.1、array.flatMap()的语法及作用

①语法

②返回值

③用途

三、array.flat()与array.flatMap() 的主要区别

3.1、映射与展平

3.2、参数接受差异

3.3、适用场景的差异

3.3.1、处理某种JSON响应数据

3.3.2、处理表格数据

3.3.3、处理用户评论(带有附加信息的数据)

3.3.4、处理文件系统路径

四、总结


一、array.flat()方法

1.1、array.flat()的语法及使用

①语法

        array.flat()方法接受一个可选的参数,该参数指定要展平的深度。如果不提供参数,默认深度为1,意味着它只会展平一层嵌套数组。如果该参数为Infinity,则将数组完全展开(为一维数组)。

②返回值

        返回一个新数组,其中包含原数组及其所有子数组的元素。

③用途

        array.flat()方法用于将一个嵌套数组(数组中的数组)展平成一个一维数组。

        当处理嵌套数组时,array.flat()非常有用,特别是需要将数组简化为单一维度,以便进行迭代或其他操作。

// 基本语法示范
const nestedArray = [1, [2, [3, 4]], 5];
const flatArray = nestedArray.flat(); // 默认深度为1,结果为 [1, 2, [3, 4], 5]
const deeplyFlatArray = nestedArray.flat(2); // 深度为2,结果为 [1, 2, 3, 4, 5]

二、array.flatMap() 方法

2.1、array.flatMap()的语法及作用

①语法

        array.flatMap()方法接受一个映射函数作为参数,该函数定义了如何转换数组中的每个元素。

②返回值

        返回一个新数组,其中包含映射函数返回的每个数组的展平元素。

③用途

        array.flatMap()方法不仅将嵌套数组展平,还允许你指定一个映射函数来转换数组中的每个元素,然后再进行展平。

        array.flatMap()在你需要在展平数组的同时对数组元素进行某种转换时非常有用。例如,当你需要将每个元素复制或转换为另一种形式时。

// 基础用法示范

const numbers = [1, 2, 3, 4];
const flatMappedArray = numbers.flatMap(num => [num, num * 2]); // 结果为 [1, 2, 2, 4, 3, 6, 4, 8]

三、array.flat()与array.flatMap() 的主要区别

3.1、映射与展平

        array.flat()仅负责展平数组,不涉及元素的转换;array.flatMap()结合了映射和展平,允许你在展平之前对元素进行转换。

        这里就有点像array.map + array.flat() - 超过1层的展平 = array.flatMap()。这个方法的语义化很明显,但是也可以通过嵌套的使用来实现基于array.flatMap()的映射和高维展平。

// flatMap中嵌套flat来实现复杂的展平

const complexArray = [
  { strings: ['a', 'b'], numbers: [1, 2] },
  { strings: ['c', 'd'], numbers: [3, 4] }
];

const result = complexArray.flatMap(obj => {
  // 首先,使用flatMap映射每个字符串到一个包含字符串和对应数字的数组
  return obj.strings.flatMap(str => {
    // 然后,再次使用flatMap映射每个数字到一个包含字符串和数字的数组
    return obj.numbers.map(num => [str, num]);
  });
}).flat(Infinity); // 使用Infinity确保所有层级都被展平

console.log(result);


// 结果为:

[
  'a', 1, 'a', 2, 'b', 1, 'b', 2,
  'c', 3, 'c', 4, 'd', 3, 'd', 4
]




const result2 = complexArray.flatMap(obj => {
  // 对于每个对象,创建一个由字符串和数字组成的子数组的新数组
  return obj.strings.flatMap(str => {
    // 对于每个字符串,创建一个由该字符串和每个数字组成的子数组
    return obj.numbers.map(num => [str, num]);
  });
});

console.log(result2);

// 结果为:

[
  ['a', 1], ['a', 2], ['b', 1], ['b', 2],
  ['c', 3], ['c', 4], ['d', 3], ['d', 4]
]

3.2、参数接受差异

        array.flat()接受一个可选的深度参数。其中Infinity可以将数组展平到一维。

        array.flatMap()接受一个映射函数作为参数。如果要进行跨纬度展平(比如三维展平成一维),需要使用嵌套或者链式调用。

3.3、适用场景的差异

        当你只需要简单地展平数组时,使用array.flat()。

        当你需要在展平数组的同时对数组元素进行转换时,使用array.flatMap()。

        以下案例能帮你更好的理解rray.flat()与array.flatMap() 的使用场景差异:

3.3.1、处理某种JSON响应数据

        假设你从API获取了一个JSON响应,其中包含了嵌套的数组数据,你需要将这些数据展平以便于进一步处理。

// API响应如下:
const apiResponse = [[{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }], [{ id: 3, name: 'Charlie' }]];


// 使用.flat()来展平嵌套数组:
const flatUsers = apiResponse.flat();
console.log(flatUsers); // 输出: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }]


// 假设我们需要筛选出ID大于2的用户,并且转换为只包含ID的数组:
const filteredUsersIds = apiResponse.flat().filter(user => user.id > 2).map(user => user.id);
console.log(filteredUsersIds); // 输出: [3]

3.3.2、处理表格数据

        在一个Web应用中,你有一个表格,每行代表一个项目,每个项目有多个属性。现在你需要将这些属性展平,以便在图表中展示。

// 表格数据如下:
const tableData = [
  { project: 'A', attributes: ['Size', 'Color'] },
  { project: 'B', attributes: ['Weight', 'Material'] }
];

// 使用.flat()来展平属性数组:
const flatAttributes = tableData.flatMap(row => row.attributes);
console.log(flatAttributes); // 输出: ['Size', 'Color', 'Weight', 'Material']

// 假设我们需要创建一个包含项目和属性的数组:
const projectAttributes = tableData.flatMap(row => row.attributes.map(attr => [row.project, attr]));
console.log(projectAttributes); // 输出: [['A', 'Size'], ['A', 'Color'], ['B', 'Weight'], ['B', 'Material']]

3.3.3、处理用户评论(带有附加信息的数据)

        在一个社交媒体应用中,用户可以对帖子进行评论,每个评论可能包含多个回复。你需要将所有评论和回复展平,以便进行搜索或索引。

// 假设评论数据如下:
const comments = [
  { user: 'User1', comment: 'Great post!', replies: ['Reply1', 'Reply2'] },
  { user: 'User2', comment: 'Thanks!', replies: ['Reply3'] }
];

// 使用.flat()来展平回复数组:
const flatReplies = comments.flatMap(comment => comment.replies);
console.log(flatReplies); // 输出: ['Reply1', 'Reply2', 'Reply3']

// 假设我们需要创建一个包含用户和评论/回复的数组:
const commentReplies = comments.flatMap(comment => 
  comment.replies.map(reply => ({ user: comment.user, text: reply }))
);
console.log(commentReplies); // 输出: [{ user: 'User1', text: 'Reply1' }, { user: 'User1', text: 'Reply2' }, { user: 'User2', text: 'Reply3' }]

3.3.4、处理文件系统路径

        在一个文件管理应用中,你需要处理文件系统路径,这些路径可能是嵌套的。

// 假设文件路径如下:
const filePaths = [['Documents', 'Projects'], ['Pictures', ['Holiday', 'Birthday']]];

// 使用.flat()来展平路径数组:
const flatPaths = filePaths.flat(2); // 指定深度为2
console.log(flatPaths); // 输出: ['Documents', 'Projects', 'Pictures', 'Holiday', 'Birthday']

// 假设我们需要为每个路径添加文件类型:
const fileTypes = [['Documents', '.txt'], ['Pictures', ['Holiday', '.jpg'], ['Birthday', '.png']]];

const formattedPaths = fileTypes.flatMap(dir => 
  dir.flatMap(file => file.endsWith('.jpg') ? [`Image: ${file}`] : [])
);
console.log(formattedPaths); // 输出: ['Image: Holiday.jpg']

四、总结

        理论上array.flat()能做的事情,array.flatMap()都可以做,但是array.flat()更简单,占用内存更少,执行更快。

        这个相对冷门一些,w3school上都没有相关教程,看到就是赚到,收藏就是财富!

        丰富的前端内容请看:各种前端问题的技巧和解决方案

        自引链接:多维数组操作,不要再用遍历循环foreach了!来试试数组展平的小妙招!

        博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

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

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

相关文章

Nature 审稿人:值得关注的里程碑!段路明研究组首次实现基于数百离子量子比特的量子模拟计算

2024年5月30日,清华大学最新科研成果发表于Nature(自然),这项成果被Nature审稿人称为“量子模拟领域的巨大进步”“值得关注的里程碑”!究竟是什么样的成果值得这样的赞誉呢? 该成果就是中国科学院院士、清…

vue3 前端实现导出下载pdf文件

这样的数据实现导出 yourArrayBufferOrByteArray 就是后端返回数据 // 创建Blob对象const blob new Blob([new Uint8Array(res)], { type: application/pdf })// 创建一个表示该Blob的URLconst url URL.createObjectURL(blob);// 创建一个a标签用于下载const a document.cr…

Vulnhub项目:Thales:1

1、靶机地址 靶机地址:Thales: 1 ~ VulnHub 这个靶机在做的时候有两种思路,下面进行详细渗透过程。 2、渗透过程 来来来,搞起!目标56.162,本机56.160 探测,探测,22,8080&#xf…

位置参数

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 位置参数也称必备参数,是必须按照正确的顺序传到函数中,即调用时的数量和位置必须和定义时是一样的。 (1&#x…

Java电商平台-开放API接口签名验证(小程序/APP)

说明:在实际的生鲜业务中,不可避免的需要对外提供api接口给外部进行调用. 这里就有一个接口安全的问题需要沟通了。下面是干货: 接口安全问题 请求身份是否合法? 请求参数是否被篡改? 请求是否唯一? AccessKey&am…

利用“记忆化搜索“解斐波那契数

一、题目描述 求第 n 个斐波那契数。 二、 利用"记忆化搜索"解斐波那契数 什么是记忆化搜索?记忆化搜索就是带有备忘录的递归。 我们先来看一下使用递归来解斐波那契数的这个过程,假设求第5个斐波那契数F(5)。 由图可见,要重复计…

P3881

最小值最大 二分:枚举两个牛之间的最小距离,左端点是1,右端点是篱笆总长度。 Check数组: 如果两头牛之间距离是Mid不合法,则返回0(false); 如果两头牛之间距离是Mid合法&#xf…

【AVL Design Explorer DOE】

AVL Design Explorer DOE 1、关于DOE的个人理解2、DOE参考资料-知乎2.1 DOE发展及基本类型2.2 DOE应用场景2.3 Mintab 中的 DOE工具3、AVL Design Explorer DOE示例 1、关于DOE的个人理解 仿真和试验一样,就像盲人摸象,在不知道大象的全景之前&#xff…

【Leetcode每日一题】 综合练习 - 组合(难度⭐⭐)(78)

1. 题目解析 题目链接:77. 组合 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 题目要求我们从 1 到 n 的整数集合中选择 k 个数的所有组合,且组合中的元素不考虑顺序。这意味着集合 [1, 2] 和…

【Elasticsearch】IK分词器的下载及使用

安装IK分词器 网址:https://github.com/infinilabs/analysis-ik 3.1.在线安装ik插件(较慢,不推荐) # 进入容器内部 es为容器名称 docker exec -it es /bin/bash# 在线下载并安装 7.17.21为镜像版本要与之前保持一致 ./bin/elasticsearch-pl…

C++_list简单源码剖析:list模拟实现

文章目录 🚀1. ListNode模板🚀2. List_iterator模板(重要)🌱2.1 List_iterator的构造函数🌱2.2 List_iterator的关于ListNode的行为 🚀3. Reverse_list_iterator模板(拓展)🚀4. List模板(核心)&#x1f331…

stack和queue(1)

一、stack的简单介绍和使用 1.1 stack的介绍 1.stack是一种容器适配器,专门用在具有先进后出,后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入和弹出操作。 2.stack是作为容器适配器被实现的,容器适配器即是…

复习leetcode第二题:两数相加

本文会给出笔者自己的解答(代码较为冗余,其实就是屎山代码)以及优秀代码的解析 下图是题目 解法1(笔者所使用的办法): 解题思路: 以下思路是基于示例1(上图)思考的 步骤…

前端Vue小兔鲜儿电商项目实战Day05

一、登录 - 整体认识和路由配置 1. 整体认识 登录页面的主要功能就是表单校验和登录退出业务 ①src/views/Login/index.vue <script setup></script><template><div><header class"login-header"><div class"container m-…

【React】封装一个好用方便的消息框(Hooks Bootstrap 实践)

引言 以 Bootstrap 为例&#xff0c;使用模态框编写一个简单的消息框&#xff1a; import { useState } from "react"; import { Modal } from "react-bootstrap"; import Button from "react-bootstrap/Button"; import bootstrap/dist/css/b…

根据状态转移图实现时序电路 (三段式状态机)

看图编程 * ** 代码 module seq_circuit(input C ,input clk ,input rst_n,output wire Y ); reg [1:0] current_stage ; reg [1:0] next_stage ; reg Y_reg; //输出//第一段 &#xff1a; 初始化当前状态和…

TensorFlow Playground神经网络演示工具使用方法详解

在现代机器学习领域,神经网络无疑是一个重要的研究方向。然而,对于许多初学者来说,神经网络的概念和实际操作可能显得相当复杂。幸运的是,TensorFlow Playground 提供了一个交互式的在线工具,使得我们可以直观地理解和实验神经网络的基本原理。在这篇博客中,我们将详细介…

Spring Boot 项目中使用 JSP

文章目录 Spring Boot 项目中使用 JSP项目结构引入依赖包编写页面和后台运行方式一&#xff1a;Maven 命令运行方式二&#xff1a;在 IDEA 中运行方式三&#xff1a;打 war 包部署运行 Spring Boot 项目中使用 JSP 在 Spring Boot 项目中不是不可以使用 JSP 。想在 Spring Boo…

Fully Convolutional Networks for Semantic Segmentation--论文笔记

论文笔记 资料 1.代码地址 2.论文地址 https://arxiv.org/abs/1411.4038 3.数据集地址 论文摘要的翻译 卷积网络是强大的视觉模型&#xff0c;可以产生特征层次结构。我们表明&#xff0c;卷积网络本身&#xff0c;经过端到端&#xff0c;像素对像素的训练&#xff0c;在…

【NPS】微软NPS配置802.1x,验证域账号,动态分配VLAN(有线网络篇)

上两篇中介绍了如何配置NPS和在WLC上如何配置802.1X来实现验证域账号和动态分配VLAN&#xff0c;802.1x协议作为一种成熟的身份验证框架&#xff0c;不仅适用于无线网络&#xff0c;同样也适用于有线网络环境。这里我们将介绍如何在有线网络中部署802.1x认证&#xff0c;以验证…