2023-05-02 08:47:21
在JavaScript中,从嵌套对象数组中高效提取唯一属性值,推荐使用Set数据结构结合数组方法(如flatMap或map),其性能与简洁性均优于传统循环与条件判断方法。
方法一:传统循环与条件判断(indexOf)实现逻辑通过双重循环遍历主数组和嵌套的subjects数组,在将每个学科名称添加到结果数组前,返正使用indexOf检查是否已存在。若不存在(返回-1),则添加。
初始化空数组allUniqueSubjects_indexOf存储唯一值。
外层循环遍历data中的每个事件对象,解构出subjects数组。
内层循环遍历subjects,对每个学科对象s,检查s.name是否在allUniqueSubjects_indexOf中。
若不存在则添加,最终输出唯一值列表。
示例代码
const allUniqueSubjects_indexOf = [];for (const { subjects } of data) { subjects.forEach((s) => { if (allUniqueSubjects_indexOf.indexOf(s.name) === -1) { allUniqueSubjects_indexOf.push(s.name); } });}优缺点
优点:逻辑直观,适合初学者理解。漏顷悔
缺点:indexOf每次需遍历整个结果数组,时间复杂度为O(NMK)(N为事件数,M为平均学科数,K为结果数组大小)。数据量大时性能显著下降,不适用于生产环境的高性能需求。
实现逻辑Set自动存储唯一值,利用其特性可高效去重。步骤如下:
初始化临时数组allNamesWithDuplicates存储所有学科名称(含重复项)。
遍历data,将每个s.name添加到临时数组。
将临时数组传入new Set()构造函数,自动去重。
使用扩展运算符...将Set转换回数组,得到最终结果。
示例代码
const allNamesWithDuplicates = [];for (const { subjects } of data) { subjects.forEach((s) => { allNamesWithDuplicates.push(s.name); });}const allUniqueSubjects_set = [...new Set(allNamesWithDuplicates)];优化版本(链式调用)结合flatMap和Set,代码更简洁:
const allUniqueSubjects_optimized = [...new Set( data.flatMap(event => event.subjects.map(s => s.name)))];优缺点
优点:
性能高效:Set的add和has操作平均时间复杂度为O(1),去重过程不受数据规模影响。
代码简洁:链式调用(如flatMap+Set)可一行实现,可读性强。
缺点:需ES6+环境支持(现代浏览器和Node.js均兼容)。
推荐实践:
从嵌套对象数组中提取唯一属性值时,Set数据结构是最佳选择。其高效去重机制和现代JavaScript的链式调用能力,使其在性能和代码质量上均优于传统方法。对于大多数场景,直接使用[...new Set(data.flatMap(...))]即可实现简洁高效的解决方案。