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

简介: 理论上array.flat()能做的事情,array.flatMap()都可以做,但是array.flat()更简单,占用内存更少,执行更快。 这个相对冷门一些,w3school上都没有相关教程,看到就是赚到,收藏就是财富! 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助


image.gif 编辑

一、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]

image.gif

二、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]

image.gif

三、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]
]

image.gif

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]

image.gif

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']]

image.gif

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' }]

image.gif

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']

image.gif

四、总结

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

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

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

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

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

相关文章
|
11月前
|
设计模式
ES6中新增Array.from()函数的用法详解
ES6中新增Array.from()函数的用法详解
106 1
|
1月前
|
Web App开发 存储 前端开发
别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
这类问题的重点在于能不能突破基础思路,突破基础思路是从程序员入门变成中级甚至高级的第一步,如果所有需求都通过最基础的业务逻辑来做,是得不到成长的。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
数据采集 监控 JavaScript
Array.forEach实战详解:简化循环与增强代码可读性;Array.forEach怎么用;面对大量数据时怎么提高Array.forEach的性能
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
存储 安全 Java
从源码到场景,用 5 分钟讲透 Array 和 ArrayList 的差异
大家好,我是小米,29岁的技术分享者。今天聊聊社招面试中常见的问题——Array和ArrayList的区别。数组是固定大小的容器,长度不可变,性能高;ArrayList是动态数组,可自动扩容,支持更多操作但性能稍逊。在实际开发中,根据需求选择:高性能、固定大小选数组;灵活操作选ArrayList。希望这篇文章能帮你答出漂亮的答案!欢迎关注我的微信公众号“软件求生”,获取更多技术干货。
67 5
|
6月前
|
Python
Numpy学习笔记(一):array()、range()、arange()用法
这篇文章是关于NumPy库中array()、range()和arange()函数的用法和区别的介绍。
284 6
Numpy学习笔记(一):array()、range()、arange()用法
|
9月前
|
前端开发
let array = [{id:‘001‘,name:‘小新‘,age:5},{ id:‘002‘,name:‘小葵‘]这样数据如何遍历,拿到其中一个值,数组中装对象如何获取其中一个固定的值
let array = [{id:‘001‘,name:‘小新‘,age:5},{ id:‘002‘,name:‘小葵‘]这样数据如何遍历,拿到其中一个值,数组中装对象如何获取其中一个固定的值
|
11月前
|
JSON 数据格式 C++
C++ JSON库 nlohmann::basic_json::array 的用法
C++ JSON库 nlohmann::basic_json::array 的用法
737 1
|
11月前
|
SQL XML Java
<foreach>元素中collection=list改成collection=array
<foreach>元素中collection=list改成collection=array
读boost::multi_array有感,多维数组实现(非类型模板,偏特化)
读boost::multi_array有感,多维数组实现(非类型模板,偏特化)
|
存储 容器
2023-3-3-std::array的用法
2023-3-3-std::array的用法
162 0

热门文章

最新文章

  • 1
    Java 中数组Array和列表List的转换
  • 2
    通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据和性能优化,reduce()的使用详解(附实际应用代码)
  • 3
    JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
  • 4
    JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
  • 5
    JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
  • 6
    深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
  • 7
    通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
  • 8
    别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
  • 9
    通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
  • 10
    AttributeError: module ‘numpy‘ has no attribute ‘array‘解决办法